// --- BEGIN COPYRIGHT BLOCK --- // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; // version 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301 USA // // Copyright (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- #ifdef __cplusplus extern "C" { #endif #ifdef XP_WIN32 #define TOKENDB_PUBLIC __declspec(dllexport) #else /* !XP_WIN32 */ #define TOKENDB_PUBLIC #endif /* !XP_WIN32 */ /* _________________________________________________________________ ** ** Tokendb Module Headers ** _________________________________________________________________ */ #include #include #include #ifndef XP_WIN32 #include /* sleep */ #else /* XP_WIN32 */ #include #endif /* XP_WIN32 */ #include "nspr.h" #include "prio.h" #include "plstr.h" #include "prmem.h" #include "prtime.h" #include "prthread.h" #include "cert.h" #include "regex.h" #include "nss3/base64.h" #include "httpd/httpd.h" #include "httpd/http_config.h" #include "httpd/http_log.h" #include "httpd/http_protocol.h" #include "httpd/http_main.h" #include "httpd/http_request.h" #include "apr_strings.h" #include "cms/CertEnroll.h" #include "engine/RA.h" #include "tus/tus_db.h" #include "processor/RA_Processor.h" #include "selftests/SelfTest.h" extern TOKENDB_PUBLIC char *nss_var_lookup( apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, char *var ); /* _________________________________________________________________ ** ** Tokendb Module Definitions ** _________________________________________________________________ */ #define JS_START "\n" #define CMS_TEMPLATE_TAG "" #define MAX_INJECTION_SIZE 5120 #define MAX_OVERLOAD 20 #define LOW_INJECTION_SIZE 2048 #define SHORT_LEN 256 #define BASE64_HEADER "-----BEGIN CERTIFICATE-----\n" #define BASE64_FOOTER "-----END CERTIFICATE-----\n" #define TOKENDB_OPERATORS_IDENTIFIER "TUS Operators" #define TOKENDB_AGENTS_IDENTIFIER "TUS Agents" #define TOKENDB_ADMINISTRATORS_IDENTIFIER "TUS Administrators" #define OP_PREFIX "op.format" #define NUM_PROFILES_TO_DISPLAY 15 #define NUM_ENTRIES_PER_PAGE 25 #define MAX_LEN_PROFILES_TO_DISPLAY 1000 #define error_out(msg1,msg2) \ PR_snprintf(injection, MAX_INJECTION_SIZE, \ "%s%s%s%s%s", JS_START, "var error = \"Error: ", \ msg1,"\";\n", JS_STOP ); \ buf = getData( errorTemplate, injection ); \ ap_log_error( ( const char * ) "tus", __LINE__, \ APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, \ ( const char * ) msg2 ); \ ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); #define ldap_error_out(msg1,msg2) \ PR_snprintf( injection, MAX_INJECTION_SIZE, \ "%s%s%s%s%s%s", JS_START, \ "var error = \"", msg1, \ ldap_err2string( status ), \ "\";\n", JS_STOP ); \ buf = getData( errorTemplate, injection ); \ ap_log_error( ( const char * ) "tus", __LINE__, \ APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, \ ( const char * ) msg2, \ ldap_err2string( status ) ); \ ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); #define post_ldap_error(msg) \ ap_log_error( ( const char * ) "tus", __LINE__, \ APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, \ (const char *) msg, ldap_err2string( status ) ); #define get_cfg_string(cname, vname) \ if( ( s = PL_strstr( buf, cname ) ) != NULL ) { \ s += PL_strlen( cname ); \ v = s; \ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && \ ( PRUint32 ) ( s - buf ) < size ) { \ s++; \ } \ n = s - v; \ s = PL_strndup( v, n ); \ if( s != NULL ) { \ if( vname != NULL ) { \ PL_strfree( vname ); \ vname = NULL; \ } \ vname = s; \ } else { \ do_free(buf); \ return 0; \ } \ } #define get_cfg_int(cname, vname) \ if( ( s = PL_strstr( buf, cname ) ) != NULL ) { \ s += PL_strlen( cname ); \ v = s; \ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && \ ( PRUint32 ) ( s - buf ) < size ) { \ s++; \ } \ n = s - v; \ s = PL_strndup( v, n ); \ if( s != NULL ) { \ char *endptr = NULL; \ errno = 0; \ vname = strtol(s, &endptr, 10);\ if ((errno == ERANGE && (vname == LONG_MAX || vname == LONG_MIN)) \ || (endptr == s)) { \ vname=0; \ } \ do_free(s); \ } else { \ do_free(buf); \ do_free(s); \ return 0; \ } \ } /** * Provide reasonable defaults for some defines. */ enum MOD_TOKENDB_BOOL { MOD_TOKENDB_FALSE = 0, MOD_TOKENDB_TRUE = 1 }; #define MAX_TOKEN_UI_STATE 6 enum token_ui_states { TOKEN_UNINITIALIZED = 0, TOKEN_DAMAGED =1, TOKEN_PERM_LOST=2, TOKEN_TEMP_LOST=3, TOKEN_FOUND =4, TOKEN_TEMP_LOST_PERM_LOST =5, TOKEN_TERMINATED = 6 }; /* _________________________________________________________________ ** ** Tokendb Module Request Data ** _________________________________________________________________ */ #ifdef DEBUG_Tokendb static PRFileDesc *debug_fd = NULL; #endif static char *templateDir = NULL; static char *errorTemplate = NULL; static char *indexTemplate = NULL; static char *indexAdminTemplate = NULL; static char *indexOperatorTemplate = NULL; static char *newTemplate = NULL; static char *searchTemplate = NULL; static char *searchResultTemplate = NULL; static char *searchAdminTemplate = NULL; static char *searchAdminResultTemplate = NULL; static char *searchActivityTemplate = NULL; static char *searchCertificateTemplate = NULL; static char *searchCertificateResultTemplate = NULL; static char *searchActivityResultTemplate = NULL; static char *searchActivityAdminTemplate = NULL; static char *searchActivityAdminResultTemplate = NULL; static char *editTemplate = NULL; static char *editResultTemplate = NULL; static char *showTemplate = NULL; static char *showCertTemplate = NULL; static char *showAdminTemplate = NULL; static char *deleteTemplate = NULL; static char *doTokenTemplate = NULL; static char *doTokenConfirmTemplate = NULL; static char *revokeTemplate = NULL; static char *addResultTemplate = NULL; static char *deleteResultTemplate = NULL; static char *editUserTemplate = NULL; static char *searchUserResultTemplate = NULL; static char *searchUserTemplate = NULL; static char *newUserTemplate = NULL; static char *userDeleteTemplate = NULL; static char *auditAdminTemplate = NULL; static char *selfTestTemplate = NULL; static char *selfTestResultsTemplate = NULL; static char *agentSelectConfigTemplate = NULL; static char *selectConfigTemplate = NULL; static char *agentViewConfigTemplate = NULL; static char *editConfigTemplate = NULL; static char *confirmConfigChangesTemplate = NULL; static char *addConfigTemplate = NULL; static char *confirmDeleteConfigTemplate = NULL; static int maxSizeLimit = 0; static int defaultSizeLimit = 0; static int maxTimeLimit = 0; static int defaultTimeLimit = 0; static int pwLength = 0; static char *profileList = NULL; static char *transitionList = NULL; static int sendInPieces = 0; static RA_Processor m_processor; /* _________________________________________________________________ ** ** Tokendb Module Command Data ** _________________________________________________________________ */ static const char MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER[] = "TokendbConfigPathFile"; static const char MOD_TOKENDB_CONFIGURATION_FILE_USAGE[] = "Tokendb Configuration Filename prefixed by a complete path, or\n" "a path that is relative to the Apache server root."; /* _________________________________________________________________ ** ** Tokendb Module Server Configuration Creation Data ** _________________________________________________________________ */ typedef struct { char *Tokendb_Configuration_File; MOD_TOKENDB_BOOL enabled; } mod_tokendb_server_configuration; /* _________________________________________________________________ ** ** Tokendb Module Registration Data ** _________________________________________________________________ */ #define MOD_TOKENDB_CONFIG_KEY tokendb_module APLOG_USE_MODULE(tokendb); static const char MOD_TOKENDB_CONFIG_KEY_NAME[] = "tokendb_module"; extern module TOKENDB_PUBLIC MOD_TOKENDB_CONFIG_KEY; /* _________________________________________________________________ ** ** Tokendb Module Helper Functions ** _________________________________________________________________ */ /** * Terminate Apache */ void tokendb_die( void ) { /* * This is used for fatal errors and here * it is common module practice to really * exit from the complete program. */ exit( 1 ); } void tokendbDebug( const char* msg ) { RA::Debug( "mod_tokendb::mod_tokendb_handler", msg); #if 0 if( debug_fd ) { PR_fprintf( debug_fd, msg ); } #endif } inline void do_free(char * buf) { if (buf != NULL) { PR_Free(buf); buf = NULL; } } inline void do_strfree(char *buf) { if (buf != NULL) { PL_strfree(buf); buf = NULL; } } inline bool valid_berval(struct berval** b) { return (b != NULL) && (b[0] != NULL) && (b[0]->bv_val != NULL); } /** * unencode * summary: takes a URL encoded string and returns an unencoded string * : must be freed by caller */ char *unencode(const char *src) { char *dest = NULL; char *dp = NULL; dest = (char *) PR_Malloc(PL_strlen(src)* sizeof(char) + 1); dp = dest; for(; PL_strlen(src) > 0 ; src++, dp++) if(*src == '+') *dp = ' '; else if(*src == '%') { int code; if (sscanf(src+1, "%2x", &code) != 1) code = '?'; *dp = code; src +=2; } else *dp = *src; *dp = '\0'; return dest; } /** * get_field * summary: used to parse query strings in get and post requests * : returns the value of the parameter following fname, in query string s. * must be freed by caller. * example: get_field("op=hello&name=foo&title=bar", "name=") returns foo */ char *get_field( char *s, const char* fname, int len) { char *end = NULL; char *tmp = NULL; char *ret = NULL; int n; if( ( s = PL_strstr( s, fname ) ) == NULL ) { return NULL; } s += strlen(fname); end = PL_strchr( s, '&' ); if( end != NULL ) { n = end - s; } else { n = PL_strlen( s ); } if (n == 0) { return NULL; } else if (n > len) { /* string too long */ return NULL; } else { tmp = (char *) PL_strndup(s,n); ret = unencode(tmp); do_free(tmp); return ret; } } /** * get_post_field * summary: get value from apr_table containing HTTP-Post values * params: post - apr_table with post data * : fname = name of post-field */ char *get_post_field( apr_table_t *post, const char *fname, int len) { char *ret = NULL; if (post) { ret = unencode(apr_table_get(post, fname)); if ((ret != NULL) && ((int) PL_strlen(ret) > len)) { PR_Free(ret); return NULL; } else { return ret; } } else { return NULL; } } char *get_post_field_s( apr_table_t *post, const char *fname) { char *ret = NULL; if (post) { ret = unencode(apr_table_get(post, fname)); return ret; } else { return NULL; } } /** * similar to get_post_field - but returns the original post data * without unencoding - used for userCert */ char *get_encoded_post_field(apr_table_t *post, const char *fname, int len) { char *ret = NULL; if (post) { ret = PL_strdup(apr_table_get(post, fname)); if ((ret != NULL) && ((int) PL_strlen(ret) > len)) { PL_strfree(ret); return NULL; } else { return ret; } } else { return NULL; } } /** * match_profile * summary: returns true if the profile passed in matches an existing profile * in the profileList read from CS.cfg. Called when confirming that * a user entered "other profile" is a real profile */ bool match_profile(const char *profile) { return RA::match_comma_list(profile, profileList); } int get_token_ui_state(char *state, char *reason) { int ret = 0; if (strcmp(state, STATE_UNINITIALIZED) == 0) { ret = TOKEN_UNINITIALIZED; } else if (strcasecmp(state, STATE_ACTIVE) == 0) { ret = TOKEN_FOUND; } else if (strcasecmp(state, STATE_LOST) == 0) { if (strcasecmp(reason, "keyCompromise") == 0) { /* perm lost or temp -> perm lost */ ret = TOKEN_PERM_LOST; } else if (strcasecmp(reason, "destroyed") == 0) { ret = TOKEN_DAMAGED; } else if (strcasecmp(reason, "onHold") == 0) { ret = TOKEN_TEMP_LOST; } } else if (strcasecmp(state, "terminated") == 0) { ret = TOKEN_TERMINATED; } else { /* state is disabled or otherwise : what to do here? */ ret = TOKEN_PERM_LOST; } return ret; } bool transition_allowed(int oldState, int newState) { /* parse the allowed transitions string and look for old:new */ char search[128]; if (transitionList == NULL) return true; PR_snprintf(search, 128, "%d:%d", oldState, newState); return RA::match_comma_list(search, transitionList); } void add_allowed_token_transitions(int token_ui_state, char *injection) { bool first = true; int i=1; char state[128]; sprintf(state, "var allowed_transitions=\""); PL_strcat(injection, state); for (i=1; i<=MAX_TOKEN_UI_STATE; i++) { if (transition_allowed(token_ui_state, i)) { if (first) { sprintf(state, "%d", i); first = false; } else { sprintf(state, ",%d", i); } PL_strcat(injection, state); } } PL_strcat(injection, "\";\n"); } char *getTemplateFile( char *fileName, int *injectionTagOffset ) { char *buf = NULL; char *s = NULL; PRFileDesc *fd = NULL; char fullFileName[4096]; PRFileInfo info; PRUint32 fileSize; PRUint32 size; PRInt32 k, n; *injectionTagOffset = -1; PR_snprintf( fullFileName, 4096, "%s/%s", templateDir, fileName ); if( PR_GetFileInfo( fullFileName, &info ) != PR_SUCCESS ) { return buf; } fileSize = info.size; size = fileSize + 1; buf = ( char * ) PR_Malloc( size ); if( buf == NULL ) { return buf; } fd = PR_Open( fullFileName, PR_RDONLY, 00400 ); if( fd == NULL ) { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return NULL; } k = 0; while( ( n = PR_Read( fd, &buf[k], fileSize-k ) ) > 0 ) { k += n; if( ( PRUint32 ) k >= fileSize ) { break; } } if( fd != NULL ) { PR_Close( fd ); fd = NULL; } if( n < 0 || ( ( PRUint32 ) k > fileSize ) ) { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return NULL; } buf[k] = '\0'; if( ( s = PL_strstr( buf, CMS_TEMPLATE_TAG ) ) != NULL ) { *injectionTagOffset = PL_strlen( buf ) - PL_strlen( s ); } return buf; } char *getData( char *fileName, char *injection ) { char *buf = NULL; char *s = NULL; PRFileDesc *fd = NULL; char fullFileName[4096]; PRFileInfo info; PRUint32 fileSize; PRUint32 size, len; PRUint32 injectionSize; PRInt32 k, n; PR_snprintf( fullFileName, 4096, "%s/%s", templateDir, fileName ); if( PR_GetFileInfo( fullFileName, &info ) != PR_SUCCESS ) { return buf; } fileSize = info.size; size = fileSize; injectionSize = 0; if( injection != NULL && PL_strlen( injection ) > 0 ) { injectionSize = PL_strlen( injection ); size += injectionSize; } size++; buf = ( char * ) PR_Malloc( size ); if( buf == NULL ) { return buf; } fd = PR_Open( fullFileName, PR_RDONLY, 00400 ); if( fd == NULL ) { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return NULL; } k = 0; while( ( n = PR_Read( fd, &buf[k], fileSize-k ) ) > 0 ) { k += n; if( ( PRUint32 ) k >= fileSize ) { break; } } if( fd != NULL ) { PR_Close( fd ); fd = NULL; } if( n < 0 || ( ( PRUint32 ) k > fileSize ) ) { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return NULL; } buf[k] = '\0'; if( injectionSize > 0 ) { if( ( s = PL_strstr( buf, CMS_TEMPLATE_TAG ) ) != NULL ) { len = PL_strlen( s ) - PL_strlen( CMS_TEMPLATE_TAG ); memmove( s + injectionSize, s + PL_strlen( CMS_TEMPLATE_TAG ), len + 1 ); memcpy( s, injection, injectionSize ); } } return buf; } /** * returns string with special characters escaped. Caller must free the contents */ char *escapeSpecialChars(char* src) { char *ret; int i =0; if (PL_strlen(src) == 0) { return PL_strdup(src); } ret = (char *)PR_Malloc(PL_strlen(src) * 2 + 1); while (*src != '\0') { if (*src == '"') { ret[i++] = '\\'; ret[i++] = '"'; } else { ret[i++] = *src; } src++; } ret[i]='\0'; return ret; } void getCertificateFilter( char *filter, char *query ) { char *uid = NULL; char *tid = NULL; char *end = NULL; char *cn = NULL; char *view = NULL; int len = 0; int i = 0; tid = PL_strstr( query, "tid=" ); uid = PL_strstr( query, "uid=" ); cn = PL_strstr( query, "cn=" ); view = PL_strstr( query, "op=view" ); if( view == NULL ) { view = PL_strstr( query, "op=show" ); } filter[0] = '\0'; if( tid == NULL && uid == NULL && cn == NULL ) { PL_strcat( filter, "(tokenID=*)" ); return; } if( tid != NULL && uid != NULL && view != NULL ) { PL_strcat( filter, "(&" ); } if( tid != NULL ) { PL_strcat( filter, "(tokenID=" ); end = PL_strchr( tid, '&' ); len = PL_strlen( filter ); if( end != NULL ) { i = end - tid - 4; if( i > 0 ) { memcpy( filter+len, tid+4, i ); } filter[len+i] = '\0'; } else { PL_strcat( filter, tid+4 ); } if( view != NULL ) { PL_strcat( filter, "*)" ); } else { PL_strcat( filter, ")" ); } } if( uid != NULL && view != NULL ) { PL_strcat( filter, "(tokenUserID=" ); end = PL_strchr( uid, '&' ); len = PL_strlen( filter ); if( end != NULL ) { i = end - uid - 4; if( i > 0 ) { memcpy( filter+len, uid+4, i ); } filter[len+i] = '\0'; } else { PL_strcat( filter, uid+4 ); } PL_strcat( filter, "*)" ); /* PL_strcat( filter, ")" ); */ } if( cn != NULL ) { PL_strcat( filter, "(cn=" ); end = PL_strchr( cn, '&' ); len = PL_strlen( filter ); if( end != NULL ) { i = end - cn - 3; if( i > 0 ) { memcpy( filter+len, cn+3, i ); } filter[len+i] = '\0'; } else { PL_strcat( filter, cn+3 ); } PL_strcat( filter, "*)" ); /* PL_strcat( filter, ")" ); */ } if(tid != NULL && uid != NULL && view != NULL) { PL_strcat( filter, ")" ); } } void getActivityFilter( char *filter, char *query ) { char *uid = NULL; char *tid = NULL; char *end = NULL; char *view = NULL; int len = 0; int i = 0; tid = PL_strstr( query, "tid=" ); uid = PL_strstr( query, "uid=" ); view = PL_strstr( query, "op=view" ); filter[0] = '\0'; if( tid == NULL && uid == NULL ) { PL_strcat( filter, "(tokenID=*)" ); } if( tid != NULL && uid != NULL && view != NULL ) { PL_strcat( filter, "(&" ); } if( tid != NULL ) { PL_strcat( filter, "(tokenID=" ); end = PL_strchr( tid, '&' ); len = PL_strlen( filter ); if( end != NULL ) { i = end - tid - 4; if( i > 0 ) { memcpy( filter+len, tid+4, i ); } filter[len+i] = '\0'; } else { PL_strcat( filter, tid+4 ); } if( view != NULL ) { PL_strcat( filter, "*)" ); } else { PL_strcat( filter, ")" ); } } if( uid != NULL && view != NULL ) { PL_strcat( filter, "(tokenUserID=" ); end = PL_strchr( uid, '&' ); len = PL_strlen( filter ); if( end != NULL ) { i = end - uid - 4; if( i > 0 ) { memcpy( filter+len, uid+4, i ); } filter[len+i] = '\0'; } else { PL_strcat( filter, uid+4 ); } PL_strcat( filter, "*)" ); /* PL_strcat( filter, ")" ); */ } if( tid != NULL && uid != NULL && view != NULL) { PL_strcat( filter, ")" ); } } /** * get_user_filter * summary: returns an ldap search filter used for displaying * user data when searching users based on uid, firstName and lastName * params: filter - ldap search filter. Resu;t returned here. * query - query string passed in */ void getUserFilter (char *filter, char *query) { char *uid = NULL; char *firstName = NULL; char *lastName = NULL; uid = get_field(query, "uid=", SHORT_LEN); firstName = get_field(query, "firstName=", SHORT_LEN); lastName = get_field(query, "lastName=", SHORT_LEN); filter[0] = '\0'; if ((uid == NULL) && (firstName == NULL) && (lastName ==NULL)) { PL_strcat(filter, "(objectClass=Person"); } else { PL_strcat(filter, "(&(objectClass=Person)"); } if (uid != NULL) { PL_strcat(filter, "(uid="); PL_strcat(filter, uid); PL_strcat(filter,")"); } if (lastName != NULL) { PL_strcat(filter, "(sn="); PL_strcat(filter, lastName); PL_strcat(filter,")"); } if (firstName != NULL) { PL_strcat(filter, "(givenName="); PL_strcat(filter, firstName); PL_strcat(filter,")"); } PL_strcat(filter, ")"); do_free(uid); do_free(firstName); do_free(lastName); } /** * add_profile_filter * summary: returns an ldap search filter which is a concatenation * of the authorized profile search filter and the regular search * filter. To be freed by caller. * params: filter - search filter * auth_filter: authorized profiles filter */ char *add_profile_filter( char *filter, char *auth_filter) { char *ret; int size; char no_auth_filter[] = "(tokenType=\"\")"; if (filter == NULL) return NULL; if ((auth_filter == NULL) || (PL_strstr( auth_filter, ALL_PROFILES))) { ret = PL_strdup(filter); } else if (PL_strstr( auth_filter, NO_PROFILES)) { size = (PL_strlen(filter) + PL_strlen(no_auth_filter) + 4) * sizeof(char); ret = (char *) PR_Malloc(size); PR_snprintf(ret, size, "%s%s%s%s", "(&", filter,no_auth_filter, ")"); } else { size = (PL_strlen(filter) + PL_strlen(auth_filter) + 4) * sizeof(char); ret = (char *) PR_Malloc(size); PR_snprintf(ret, size, "%s%s%s%s", "(&", filter, auth_filter, ")"); } return ret; } void getFilter( char *filter, char *query ) { char *uid = NULL; char *tid = NULL; char *end = NULL; char *view = NULL; int len = 0; int i = 0; tid = PL_strstr( query, "tid=" ); uid = PL_strstr( query, "uid=" ); view = PL_strstr( query, "op=view" ); filter[0] = '\0'; if( tid == NULL && uid == NULL ) { PL_strcat( filter, "(cn=*)" ); } if( tid != NULL && uid != NULL && view != NULL ) { PL_strcat( filter, "(&" ); } if( tid != NULL ) { PL_strcat( filter, "(cn=" ); end = PL_strchr( tid, '&' ); len = PL_strlen( filter ); if( end != NULL ) { i = end - tid - 4; if( i > 0 ) { memcpy( filter+len, tid+4, i ); } filter[len+i] = '\0'; } else { PL_strcat( filter, tid+4 ); } if (view != NULL) { PL_strcat( filter, "*)" ); } else { PL_strcat( filter, ")" ); } } if( uid != NULL && view != NULL ) { PL_strcat( filter, "(tokenUserID=" ); end = PL_strchr( uid, '&' ); len = PL_strlen( filter ); if( end != NULL ) { i = end - uid - 4; if( i > 0 ) { memcpy( filter+len, uid+4, i ); } filter[len+i] = '\0'; } else { PL_strcat( filter, uid+4 ); } PL_strcat( filter, "*)" ); /* PL_strcat( filter, ")" ); */ } if( tid != NULL && uid != NULL && view != NULL ) { PL_strcat( filter, ")" ); } } void getCN( char *cn, char *query ) { char *tid = NULL; char *end = NULL; int i = 0; cn[0] = '\0'; tid = PL_strstr( query, "tid=" ); if( tid != NULL ) { end = PL_strchr( tid, '&' ); if( end != NULL ) { i = end - tid - 4; if( i > 0 ) { memcpy( cn, tid+4, i ); } cn[i] = '\0'; } else { PL_strcat( cn, tid+4 ); } } } void getTemplateName( char *cn, char *query ) { char *tid = NULL; char *end = NULL; int i = 0; cn[0] = '\0'; tid = PL_strstr( query, "template=" ); if( tid != NULL ) { end = PL_strchr( tid, '&' ); if( end != NULL ) { i = end - tid - 4; if( i > 0 ) { memcpy( cn, tid+4, i ); } cn[i] = '\0'; } else { PL_strcat( cn, tid+4 ); } } } char *parse_modification_number( char *s ) { char *end = NULL; int n; if( ( s = PL_strstr( s, "m=" ) ) == NULL ) { return NULL; } s += 2; end = PL_strchr( s, '&' ); if( end != NULL ) { n = end - s; } else { n = PL_strlen( s ); } return PL_strndup( s, n ); } char **parse_modification_number_change( char *s ) { char *end = NULL; char **v = NULL; char tmp[32]; int n, m; end = PL_strchr( s, '&' ); if( end != NULL ) { n = end - s; if( n > 0 ) { memcpy( tmp, s, n ); } tmp[n] = '\0'; } else { n = PL_strlen( s ); PL_strcpy( tmp, s ); } m = atoi( tmp ); m++; PR_snprintf( tmp, 32, "%d", m ); n = PL_strlen( tmp ); if( ( v = allocate_values( 1, n+1 ) ) == NULL ) { return NULL; } PL_strcpy( v[0], tmp ); return v; } char **parse_status_change( char *s ) { char *end = NULL; char **v = NULL; int n; end = PL_strchr( s, '&' ); if( end != NULL ) { n = end - s; } else { n = PL_strlen( s ); } if( ( v = allocate_values( 1, n+1 ) ) == NULL ) { return NULL; } PL_strncpy( v[0], s, n ); return v; } char **parse_uid_change( char *s ) { char *end = NULL; char *p = NULL; char *q = NULL; char **v = NULL; int i, k, n, m; end = PL_strchr( s, '&' ); if( end != NULL ) { n = end - s; } else { n = PL_strlen( s ); } k = n; p = s; m = 1; while( k > 0 ) { if( ( p = PL_strnchr( p, ',', k ) ) == NULL ) { break; } p++; k = n - ( p - s ); m++; } if( ( v = allocate_values( m, n+1 ) ) == NULL ) { return NULL; } if( m > 1 ) { k = n; p = s; i = 0; while( k > 0 ) { if( ( q = PL_strnchr( p, ',', k ) ) != NULL ) { PL_strncpy( v[i], p, q-p ); q++; p = q; k = n - ( p - s ); i++; v[i] = v[i-1] + PL_strlen( v[i-1] ) + 1; } else { PL_strncpy( v[i], p, k ); break; } } } else { PL_strncpy( v[0], s, n ); } return v; } char **parse_reason_change( char *s ) { char *end = NULL; char **v = NULL; int n; end = PL_strchr( s, '&' ); if( end != NULL ) { n = end - s; } else { n = PL_strlen( s ); } if( ( v = allocate_values( 1, n+1 ) ) == NULL ) { return NULL; } PL_strncpy( v[0], s, n ); return v; } char **parse_policy_change( char *s ) { char *end = NULL; char **v = NULL; int n; end = PL_strchr( s, '&' ); if( end != NULL ) { n = end - s; } else { n = PL_strlen( s ); } if( ( v = allocate_values( 1, n+1 ) ) == NULL ) { return NULL; } PL_strncpy( v[0], s, n ); return v; } LDAPMod **getModifications( char *query ) { LDAPMod **mods = NULL; char **v = NULL; int n = 0; int k = 0; char *s; s = query; while( ( s = PL_strchr( s, '&' ) ) != NULL ) { s++; n++; } if( n > 0 && PL_strstr( query, "&tid=" ) != NULL ) { n--; } if( n > 0 ) { n++; } else { return NULL; } mods = allocate_modifications( n ); if( mods == NULL ) { return NULL; } if( ( v = create_modification_date_change() ) == NULL ) { if( mods != NULL ) { free_modifications( mods, 0 ); mods = NULL; } return NULL; } mods[0]->mod_op = LDAP_MOD_REPLACE; mods[0]->mod_type = get_modification_date_name(); mods[0]->mod_values = v; k = 1; if( k < n && ( ( s = PL_strstr( query, "m=" ) ) != NULL ) ) { s += 2; if( ( v = parse_modification_number_change( s ) ) == NULL ) { if( mods != NULL ) { free_modifications( mods, 0 ); mods = NULL; } return NULL; } mods[k]->mod_op = LDAP_MOD_REPLACE; mods[k]->mod_type = get_number_of_modifications_name(); mods[k]->mod_values = v; k++; } if( k < n && ( ( s = PL_strstr( query, "s=" ) ) != NULL ) ) { s += 2; if( ( v = parse_status_change( s ) ) == NULL ) { if( mods != NULL ) { free_modifications( mods, 0 ); mods = NULL; } return NULL; } mods[k]->mod_op = LDAP_MOD_REPLACE; mods[k]->mod_type = get_token_status_name(); mods[k]->mod_values = v; k++; } if( k < n && ( ( s = PL_strstr( query, "uid=" ) ) != NULL ) ) { s += 4; if( ( v = parse_uid_change( s ) ) == NULL ) { if( mods != NULL ) { free_modifications( mods, 0 ); mods = NULL; } return NULL; } mods[k]->mod_op = LDAP_MOD_REPLACE; mods[k]->mod_type = get_token_users_name(); mods[k]->mod_values = v; k++; } if( k < n && ( ( s = PL_strstr( query, "tokenPolicy=" ) ) != NULL ) ) { s += 12; if( ( v = parse_policy_change( s ) ) == NULL ) { if( mods != NULL ) { free_modifications( mods, 0 ); mods = NULL; } return NULL; } mods[k]->mod_op = LDAP_MOD_REPLACE; mods[k]->mod_type = get_policy_name(); mods[k]->mod_values = v; k++; } if( k < n && ( ( s = PL_strstr( query, "tokenReason=" ) ) != NULL ) ) { s += 12; if( ( v = parse_reason_change( s ) ) == NULL ) { if( mods != NULL ) { free_modifications( mods, 0 ); mods = NULL; } return NULL; } mods[k]->mod_op = LDAP_MOD_REPLACE; mods[k]->mod_type = get_reason_name(); mods[k]->mod_values = v; k++; } return mods; } int get_tus_config( char *name ) { PRFileDesc *fd = NULL; char *buf = NULL; char *s = NULL; char *v = NULL; PRFileInfo info; PRUint32 size; int k, n; if( PR_GetFileInfo( name, &info ) != PR_SUCCESS ) { return 0; } size = info.size; size++; buf = (char *)PR_Malloc( size ); if( buf == NULL ) { return 0; } fd = PR_Open( name, PR_RDONLY, 00400 ); if( fd == NULL ) { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } k = 0; while( ( n = PR_Read( fd, &buf[k], size-k-1 ) ) > 0 ) { k += n; if( ( PRUint32 ) ( k+1 ) >= size ) { break; } } if( fd != NULL ) { PR_Close( fd ); fd = NULL; } if( n < 0 || ( ( PRUint32 ) ( k+1 ) > size ) ) { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } buf[k] = '\0'; if( ( s = PL_strstr( buf, "tokendb.templateDir=" ) ) != NULL ) { s += PL_strlen( "tokendb.templateDir=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( templateDir != NULL ) { PL_strfree( templateDir ); templateDir = NULL; } templateDir = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.errorTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.errorTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( errorTemplate != NULL ) { PL_strfree( errorTemplate ); errorTemplate = NULL; } errorTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.indexTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.indexTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( indexTemplate != NULL ) { PL_strfree( indexTemplate ); indexTemplate = NULL; } indexTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.indexAdminTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.indexAdminTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( indexAdminTemplate != NULL ) { PL_strfree( indexAdminTemplate ); indexAdminTemplate = NULL; } indexAdminTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.indexOperatorTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.indexOperatorTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( indexOperatorTemplate != NULL ) { PL_strfree( indexOperatorTemplate ); indexOperatorTemplate = NULL; } indexOperatorTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.newTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.newTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 )( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( newTemplate != NULL ) { PL_strfree( newTemplate ); newTemplate = NULL; } newTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchUserResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchUserResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 )( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { do_free(searchUserResultTemplate); searchUserResultTemplate = s; } else { do_free(buf); return 0; } } if( ( s = PL_strstr( buf, "tokendb.newUserTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.newUserTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 )( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { do_free(newUserTemplate); newUserTemplate = s; } else { do_free(buf); return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchTemplate != NULL ) { PL_strfree( searchTemplate ); searchTemplate = NULL; } searchTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchCertificateTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchCertificateTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchCertificateTemplate != NULL ) { PL_strfree( searchCertificateTemplate ); searchCertificateTemplate = NULL; } searchCertificateTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchAdminTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchAdminTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchAdminTemplate != NULL ) { PL_strfree( searchAdminTemplate ); searchAdminTemplate = NULL; } searchAdminTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchUserTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchUserTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchUserTemplate != NULL ) { PL_strfree( searchUserTemplate ); searchUserTemplate = NULL; } searchUserTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchActivityTemplate=" ) ) != NULL) { s += PL_strlen( "tokendb.searchActivityTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchActivityTemplate != NULL ) { PL_strfree( searchActivityTemplate ); searchActivityTemplate = NULL; } searchActivityTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchActivityAdminTemplate=" ) ) != NULL) { s += PL_strlen( "tokendb.searchActivityAdminTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchActivityAdminTemplate != NULL ) { PL_strfree( searchActivityAdminTemplate ); searchActivityAdminTemplate = NULL; } searchActivityAdminTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchCertificateResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchCertificateResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchCertificateResultTemplate != NULL ) { PL_strfree( searchCertificateResultTemplate ); searchCertificateResultTemplate = NULL; } searchCertificateResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchActivityResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchActivityResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchActivityResultTemplate != NULL ) { PL_strfree( searchActivityResultTemplate ); searchActivityResultTemplate = NULL; } searchActivityResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchAdminResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchAdminResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchAdminResultTemplate != NULL ) { PL_strfree( searchAdminResultTemplate ); searchAdminResultTemplate = NULL; } searchAdminResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchResultTemplate != NULL ) { PL_strfree( searchResultTemplate ); searchResultTemplate = NULL; } searchResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.deleteTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.deleteTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( deleteTemplate != NULL ) { PL_strfree( deleteTemplate ); deleteTemplate = NULL; } deleteTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.userDeleteTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.userDeleteTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( userDeleteTemplate != NULL ) { PL_strfree( userDeleteTemplate ); userDeleteTemplate = NULL; } userDeleteTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.doTokenConfirmTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.doTokenConfirmTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( doTokenConfirmTemplate != NULL ) { PL_strfree( doTokenConfirmTemplate ); revokeTemplate = NULL; } doTokenConfirmTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.doTokenTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.doTokenTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( doTokenTemplate != NULL ) { PL_strfree( doTokenTemplate ); revokeTemplate = NULL; } doTokenTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.revokeTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.revokeTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( revokeTemplate != NULL ) { PL_strfree( revokeTemplate ); revokeTemplate = NULL; } revokeTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.showAdminTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.showAdminTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( showAdminTemplate != NULL ) { PL_strfree( showAdminTemplate ); showAdminTemplate = NULL; } showAdminTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.showCertTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.showCertTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if (s != NULL) { if( showCertTemplate != NULL ) { PL_strfree( showCertTemplate ); showCertTemplate = NULL; } showCertTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.showTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.showTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( showTemplate != NULL ) { PL_strfree( showTemplate ); showTemplate = NULL; } showTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.searchActivityAdminResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.searchActivityAdminResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( searchActivityAdminResultTemplate != NULL ) { PL_strfree( searchActivityAdminResultTemplate ); searchActivityAdminResultTemplate = NULL; } searchActivityAdminResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.editUserTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.editUserTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( editUserTemplate != NULL ) { PL_strfree( editUserTemplate ); editUserTemplate = NULL; } editUserTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.editTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.editTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( editTemplate != NULL ) { PL_strfree( editTemplate ); editTemplate = NULL; } editTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.editResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.editResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( editResultTemplate != NULL ) { PL_strfree( editResultTemplate ); editResultTemplate = NULL; } editResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.addResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.addResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( addResultTemplate != NULL ) { PL_strfree( addResultTemplate ); addResultTemplate = NULL; } addResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.deleteResultTemplate=" ) ) != NULL ) { s += PL_strlen( "tokendb.deleteResultTemplate=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( deleteResultTemplate != NULL ) { PL_strfree( deleteResultTemplate ); deleteResultTemplate = NULL; } deleteResultTemplate = s; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } if( ( s = PL_strstr( buf, "tokendb.tokendb.sendInPieces=" ) ) != NULL ) { s += 13; v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { sendInPieces = atoi( s ); PL_strfree( s ); s = NULL; } else { if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return 0; } } /* keep this assignment to profileList for backwards compatibility. It has been superseded by target.Profiles.list. This should be removed in a future release */ if( ( s = PL_strstr( buf, "target.tokenType.list=" ) ) != NULL ) { s += PL_strlen( "target.tokenType.list=" ); v = s; while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && ( PRUint32 ) ( s - buf ) < size ) { s++; } n = s - v; s = PL_strndup( v, n ); if( s != NULL ) { if( profileList != NULL ) { PL_strfree( profileList ); profileList = NULL; } profileList = s; } else { do_free(buf); return 0; } } get_cfg_string("tokendb.allowedTransitions=", transitionList); get_cfg_string("tokendb.auditAdminTemplate=", auditAdminTemplate); get_cfg_string("tokendb.selfTestTemplate=", selfTestTemplate); get_cfg_string("tokendb.selfTestResultsTemplate=", selfTestResultsTemplate); get_cfg_string("tokendb.selectConfigTemplate=", selectConfigTemplate); get_cfg_string("tokendb.agentSelectConfigTemplate=", agentSelectConfigTemplate); get_cfg_string("tokendb.editConfigTemplate=", editConfigTemplate); get_cfg_string("tokendb.agentViewConfigTemplate=", agentViewConfigTemplate); get_cfg_string("tokendb.confirmConfigChangesTemplate=", confirmConfigChangesTemplate); get_cfg_string("tokendb.addConfigTemplate=", addConfigTemplate); get_cfg_string("tokendb.confirmDeleteConfigTemplate=", confirmDeleteConfigTemplate); get_cfg_string("target.Profiles.list=", profileList); get_cfg_int("general.search.sizelimit.max=", maxSizeLimit); get_cfg_int("general.search.sizelimit.default=", defaultSizeLimit); get_cfg_int("general.search.timelimit.max=", maxTimeLimit); get_cfg_int("general.search.timelimit.min=", defaultTimeLimit); get_cfg_int("general.pwlength.min=", pwLength); if( buf != NULL ) { PR_Free( buf ); buf = NULL; } tus_db_end(); return 1; } /* _________________________________________________________________ ** ** Tokendb Module Request Phase ** _________________________________________________________________ */ /** * Terminate the Tokendb module */ static apr_status_t mod_tokendb_terminate( void *data ) { /* This routine is ONLY called when this server's */ /* pool has been cleared or destroyed. */ /* Log Tokendb module debug information. */ RA::Debug( "mod_tokendb::mod_tokendb_terminate", "The Tokendb module has been terminated!" ); tus_db_end(); tus_db_cleanup(); /* Since all members of mod_tokendb_server_configuration are allocated */ /* from a pool, there is no need to unset any of these members. */ /* Shutdown all APR library routines. */ /* NOTE: This automatically destroys all memory pools. */ /* Allow the TPS/NSS Modules to perform this task. */ /* apr_terminate(); */ /* Terminate the entire Apache server */ /* NOTE: Allow the TPS/NSS Modules to perform this task. */ return OK; } /** * Initialize the Tokendb module */ static int mod_tokendb_initialize( apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *sv ) { mod_tokendb_server_configuration *sc = NULL; char *cfg_path_file = NULL; char *error = NULL; int status; /* Retrieve the Tokendb module. */ sc = ( ( mod_tokendb_server_configuration * ) ap_get_module_config( sv->module_config, &MOD_TOKENDB_CONFIG_KEY ) ); /* Check to see if the Tokendb module has been loaded. */ if( sc->enabled == MOD_TOKENDB_TRUE ) { return OK; } /* Load the Tokendb module. */ #ifdef DEBUG_Tokendb debug_fd = PR_Open( "/tmp/tus-debug.log", PR_RDWR | PR_CREATE_FILE | PR_APPEND, 00400 | 00200 ); #endif /* Retrieve the path to where the configuration files are located, and */ /* insure that the Tokendb module configuration file is located here. */ if( sc->Tokendb_Configuration_File != NULL ) { /* provide Tokendb Config File from */ /* /conf/httpd.conf */ if( sc->Tokendb_Configuration_File[0] == '/' ) { /* Complete path to Tokendb Config File is denoted */ cfg_path_file = apr_psprintf( p, "%s", ( char * ) sc->Tokendb_Configuration_File ); } else { /* Tokendb Config File is located relative */ /* to the Apache server root */ cfg_path_file = apr_psprintf( p, "%s/%s", ( char * ) ap_server_root, ( char * ) sc->Tokendb_Configuration_File ); } } else { /* Log information regarding this failure. */ ap_log_error( "mod_tokendb_initialize", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, sv, "The tokendb module was installed incorrectly since the " "parameter named '%s' is missing from the Apache " "Configuration file!", ( char * ) MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER ); /* Display information on the screen regarding this failure. */ printf( "\nUnable to start Apache:\n" " The tokendb module is missing the required parameter named" " \n'%s' in the Apache Configuration file!\n", ( char * ) MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER ); goto loser; } /* Initialize the Token DB. */ if( get_tus_config( cfg_path_file ) && get_tus_db_config( cfg_path_file ) ) { RA::Debug( "mod_tokendb::mod_tokendb_initialize", "Initializing TUS database"); if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) { if( error != NULL ) { RA::Debug( "mod_tokendb::mod_tokendb_initialize", "Token DB initialization failed: '%s'", error ); PR_smprintf_free( error ); error = NULL; } else { RA::Debug( "mod_tokendb::mod_tokendb_initialize", "Token DB initialization failed" ); } #if 0 goto loser; #endif } else { RA::Debug( "mod_tokendb::mod_tokendb_initialize", "Token DB initialization succeeded" ); } } else { RA::Debug( "mod_tokendb::mod_tokendb_initialize", "Error reading tokendb config file: '%s'", cfg_path_file ); } /* Initialize the "server" member of mod_tokendb_server_configuration. */ sc->enabled = MOD_TOKENDB_TRUE; /* Register a server termination routine. */ apr_pool_cleanup_register( p, sv, mod_tokendb_terminate, apr_pool_cleanup_null ); /* Log Tokendb module debug information. */ RA::Debug( "mod_tokendb::mod_tokendb_initialize", "The Tokendb module has been successfully loaded!" ); return OK; loser: /* Log Tokendb module debug information. */ RA::Debug( "mod_tokendb::mod_tokendb_initialize", "Failed loading the Tokendb module!" ); /* Since all members of mod_tokendb_server_configuration are allocated */ /* from a pool, there is no need to unset any of these members. */ /* Shutdown all APR library routines. */ /* NOTE: This automatically destroys all memory pools. */ apr_terminate(); /* Terminate the entire Apache server */ tokendb_die(); return DECLINED; } char *stripBase64HeaderAndFooter( char *cert ) { char *base64_data = NULL; char *data = NULL; char *footer = NULL; if( ( cert != NULL ) && ( strlen( cert ) > strlen( BASE64_HEADER ) ) ) { /* Strip off the base64 header. */ data = ( char * ) ( cert + strlen( BASE64_HEADER ) ); /* Find base64 footer. */ footer = ( char * ) strstr( ( const char * ) data, ( const char * ) BASE64_FOOTER ); if( footer != NULL ) { /* Strip off the base64 footer. */ footer[0] = '\0'; } /* Finally, store data in the base64_data storage area. */ base64_data = strdup( data ); } return base64_data; } /** * util_read * summary: called from read_post. reads posted data */ static int util_read(request_rec *r, const char **rbuf) { int rc = OK; if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) { return rc; } if (ap_should_client_block(r)) { char argsbuffer[HUGE_STRING_LEN]; int rsize, len_read, rpos=0; long length = r->remaining; *rbuf = (const char*) apr_pcalloc(r->pool, length + 1); while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) { if ((rpos + len_read) > length) { rsize = length - rpos; } else { rsize = len_read; } memcpy((char*)*rbuf + rpos, argsbuffer, rsize); rpos += rsize; } } return rc; } /** * read_post * read data in a post request and store it in an apr_table */ static int read_post(request_rec *r, apr_table_t **tab) { const char *data; const char *key, *val; int rc = OK; if((rc = util_read(r, &data)) != OK) { return rc; } if(*tab) { apr_table_clear(*tab); } else { *tab = apr_table_make(r->pool, 8); } while(*data && (val = ap_getword(r->pool, &data, '&'))) { key = ap_getword(r->pool, &val, '='); ap_unescape_url((char*)key); ap_unescape_url((char*)val); apr_table_merge(*tab, key, val); } return OK; } /** * add_authorization_data * writes variable that describe whether the user is an admin, agent or operator to the * injection data. Used by templates to determine which tabs to display */ void add_authorization_data(const char *userid, int is_admin, int is_operator, int is_agent, char *injection) { if (is_agent) { PL_strcat(injection, "var agentAuth = \"true\";\n"); } if (is_operator) { PL_strcat(injection, "var operatorAuth = \"true\";\n"); } if (is_admin) { PL_strcat(injection, "var adminAuth = \"true\";\n"); } } /** * check_injection_size * Used when the injection size can become large - as in the case where lists of tokens, certs or activities are being returned. * If the free space in injection drops below a threshold, more space is allocated. Fails if injection exceeds a certain size. * This should not happen because the number of entries to return per page is limited. * * returns 0 on success,1 on failure */ int check_injection_size(char **injection, int *psize, char *fixed_injection) { char *new_ptr = NULL; if (((*psize) - PL_strlen(*injection)) <= LOW_INJECTION_SIZE) { if ((*psize) > MAX_OVERLOAD * MAX_INJECTION_SIZE) { tokendbDebug("Error: Injection exceeds maximum size. Output will be truncated"); return 1; } if (*injection == fixed_injection) { *injection = (char *) PR_Malloc(MAX_INJECTION_SIZE + (*psize)); if (*injection != NULL) { PL_strcpy(*injection, fixed_injection); (*psize) += MAX_INJECTION_SIZE; } else { tokendbDebug("Error: Unable to allocate memory for injection. Output will be truncated"); *injection = fixed_injection; return 1; } } else { new_ptr = (char *) PR_Realloc(*injection, (*psize) + MAX_INJECTION_SIZE); if (new_ptr != NULL) { //allocation successful *injection = new_ptr; (*psize) += MAX_INJECTION_SIZE; } else { tokendbDebug("Error: Failed to reallocate memory for injection. Output will be truncated"); return 1; } } } return 0; } /* * We need to compare current values in the database entry e with new values. * If they are different, then we need to provide the audit message */ int audit_attribute_change(LDAPMessage *e, const char *fname, char *fvalue, char *msg) { struct berval **attr_values = NULL; char pString[512]=""; attr_values = get_attribute_values( e, fname ); if (attr_values != NULL) { if (fvalue == NULL) { // value has been deleted PR_snprintf(pString, 512, "%s;;no_value", fname); } else if (valid_berval(attr_values) && (strcmp(fvalue, attr_values[0]->bv_val) != 0)) { // value has been changed PR_snprintf(pString, 512, "%s;;%s", fname, fvalue); } free_values(attr_values, 1); attr_values = NULL; } else if (fvalue != NULL) { // value has been added PR_snprintf(pString, 512, "%s;;%s", fname, fvalue); } if (strlen(pString) > 0) { if (strlen(msg) != 0) PL_strncat(msg, "+", 4096 - strlen(msg)); PL_strncat(msg, pString, 4096 - strlen(msg)); } return 0; } /** * replaces all instances of a substring oldstr with newstr * must be freed by caller **/ char *replace(const char *s, const char *oldstr, const char *newstr) { char *ret = NULL; int i, count = 0; size_t newlen = PL_strlen(newstr); size_t oldlen = PL_strlen(oldstr); for (i = 0; s[i] != '\0'; i++) { if (PL_strstr(&s[i], oldstr) == &s[i]) { count++; i += oldlen - 1; } } ret = (char *) PR_Malloc(PL_strlen(s) + count * (newlen - oldlen) + 1); i = 0; while (*s) { if (PL_strstr(s, oldstr) == s) { PL_strncpy(&ret[i], newstr, newlen); i += newlen; s += oldlen; } else ret[i++] = *s++; } ret[i] = '\0'; return ret; } char *escapeString(const char *s) { char *ret, *ret1, *ret2, *ret3; ret1 = replace(s, "\"", "&dbquote"); ret2 = replace(ret1, "\'", "&singlequote"); ret3 = replace(ret2, "<", "&lessthan"); ret = replace(ret3, ">", "&greaterthan"); do_free(ret1); do_free(ret2); do_free(ret3); return ret; } char *unescapeString(const char *s) { char *ret, *ret1, *ret2, *ret3; ret1 = replace(s, "&dbquote", "\""); ret2 = replace(ret1,"&singlequote", "\'"); ret3 = replace(ret2, "&lessthan", "<"); ret = replace(ret3, "&greaterthan", ">"); do_free(ret1); do_free(ret2); do_free(ret3); return ret; } /** * determines if the parameter set named pname of type ptype * has been defined. **/ bool config_param_exists(char *ptype, char* pname) { char configname[256]=""; PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype ); const char* conf_list = RA::GetConfigStore()->GetConfigAsString( configname ); return RA::match_comma_list((const char*) pname, (char *) conf_list); } /** * takes in the type and name of the parameter set. * returns the current state and timestamp of this parameter set. * * If a parameter set is being viewed in the UI for the first time, the state is returned * as "Enabled" and the timestamp is set to the current timestamp. **/ void get_config_state_timestamp(char *type, char *name, char **pstate, char **ptimestamp) { char configname[256] = ""; bool commit_needed = false; const char *tmp_state = NULL; const char *tmp_timestamp = NULL; int status; PRLock *config_lock = RA::GetConfigLock(); PR_Lock(config_lock); PR_snprintf(configname, 256, "config.%s.%s.state", type, name); tmp_state = RA::GetConfigStore()->GetConfigAsString(configname); if ((tmp_state == NULL) && (config_param_exists(type, name))) { RA::GetConfigStore()->Add(configname, "Enabled"); commit_needed = true; *pstate = (char *) PL_strdup("Enabled"); } else { *pstate = (char *) PL_strdup(tmp_state); } PR_snprintf(configname, 256, "config.%s.%s.timestamp", type, name); tmp_timestamp = RA::GetConfigStore()->GetConfigAsString(configname); if ((tmp_timestamp == NULL) && (config_param_exists(type, name))) { char new_ts[256]; PR_snprintf(new_ts, 256, "%lld", PR_Now()); RA::GetConfigStore()->Add(configname, new_ts); commit_needed = true; *ptimestamp = (char *) PL_strdup(new_ts); } else { *ptimestamp = (char *) PL_strdup(tmp_timestamp); } PR_Unlock(config_lock); if (commit_needed) { char error_msg[512]; status = RA::GetConfigStore()->Commit(false, error_msg, 512); if (status != 0) { tokendbDebug(error_msg); } } } /** * takes in a parameter set type and name * removes any variables defining the state and timestamp. * Called when a parameter set is deleted. **/ void remove_config_state_timestamp(char *type, char *name) { char configname[256] = ""; PRLock *config_lock = RA::GetConfigLock(); PR_Lock(config_lock); PR_snprintf(configname, 256, "config.%s.%s.state", type, name); RA::GetConfigStore()->Remove(configname); PR_snprintf(configname, 256, "config.%s.%s.timestamp", type, name); RA::GetConfigStore()->Remove(configname); PR_Unlock(config_lock); } /** * takes in a parameter set type * returns true if this parameter set type must be approved/ disabled by an agent **/ bool agent_must_approve(char *conf_type) { const char* agent_list = RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list"); return RA::match_comma_list((const char*) conf_type, (char *) agent_list); } /** * This is the main function used to set the state and timestamp for parameter sets * managed by the UI. The function includes checks to enforce only allowed transitions. * * Arguments are as follows: * type: parameter set type * name: parameter set name * old_ts: old timestamp of parameter set. Used to check for concurrency conflicts. * new_state: state to transition to: one of "Enabled", "Disabled", "Pending_Approval" or "Writing" * who: role requesting the transition, one of "Agent" or "Admin" * new_config: true if this is a new parameter set, false otherwise * userid: userid of user requesting the transition, used for audit log message * * function will return 0 on success, non-zero otherwise **/ int set_config_state_timestamp(char *type, char* name, char *old_ts, const char *new_state, const char *who, bool new_config, char *userid) { char ts_name[256] = ""; char state_name[256] = ""; char writer_name[256] = ""; char new_ts[256] =""; char final_state[256] = ""; char me[256]=""; int ret =0; PRTime now; PRThread *ct = NULL; PRLock *config_lock = RA::GetConfigLock(); PR_snprintf(ts_name, 256, "config.%s.%s.timestamp", type, name); PR_snprintf(state_name, 256, "config.%s.%s.state", type, name); PR_snprintf(writer_name, 256, "config.%s.%s.writer", type, name); ct = PR_GetCurrentThread(); PR_snprintf(me, 256, "%x", ct); PR_Lock(config_lock); if (new_config) { if (agent_must_approve(type)) { RA::GetConfigStore()->Add(state_name, "Disabled"); } else { RA::GetConfigStore()->Add(state_name, "Enabled"); } now = PR_Now(); PR_snprintf(new_ts, 256, "%lld", now); RA::GetConfigStore()->Add(ts_name, new_ts); } // used to make sure auditing is correct PR_snprintf(final_state, 256, "%s", new_state); const char *cur_state = RA::GetConfigStore()->GetConfigAsString(state_name); const char *cur_writer = RA::GetConfigStore()->GetConfigAsString(writer_name, ""); const char *cur_ts = RA::GetConfigStore()->GetConfigAsString(ts_name); if ((cur_state == NULL) || (cur_ts == NULL)) { // this item has likely been deleted ret=20; goto release_and_exit; } if ((PL_strcmp(cur_ts, old_ts) != 0) && (!new_config)) { // version out of date ret=1; goto release_and_exit; } if (PL_strcmp(cur_state, new_state) == 0) { ret=0; goto release_and_exit; } if (PL_strcmp(who, "Admin")==0) { if (PL_strcmp(new_state, "Disabled")==0) { if ((PL_strcmp(cur_state, "Writing") == 0) && (PL_strcmp(me, cur_writer) == 0)) { // "Writing" to "Disabled", with me as writer, admin finishes writes after "Save" now = PR_Now(); PR_snprintf(new_ts, 256, "%lld", now); RA::GetConfigStore()->Add(ts_name, new_ts); if (agent_must_approve(type)) { RA::GetConfigStore()->Add(state_name, new_state); } else { PR_snprintf(final_state, 256, "Enabled"); RA::GetConfigStore()->Add(state_name, "Enabled"); } ret=0; goto release_and_exit; } else { ret=2; goto release_and_exit; } } else if (PL_strcmp(new_state, "Enabled")==0) { if ((!agent_must_approve(type)) && (PL_strcmp(cur_state, "Writing") == 0) && (PL_strcmp(me, cur_writer) == 0)) { now = PR_Now(); PR_snprintf(new_ts, 256, "%lld", now); RA::GetConfigStore()->Add(ts_name, new_ts); ret = 0; goto release_and_exit; } // no valid transitions for admin (if agent approval required) ret=3; goto release_and_exit; } else if (PL_strcmp(new_state, "Pending_Approval")==0) { if (PL_strcmp(cur_state, "Disabled") == 0) { // Disabled -> Pending (admin submits for approval with no changes) RA::GetConfigStore()->Add(state_name, new_state); ret=0; goto release_and_exit; } else if ((PL_strcmp(cur_state, "Writing") == 0) && (PL_strcmp(me, cur_writer) == 0)) { // Writing -> Pending. (admin finishes writes after "Submit for Approval") now = PR_Now(); PR_snprintf(new_ts, 256, "%lld", now); RA::GetConfigStore()->Add(ts_name, new_ts); RA::GetConfigStore()->Add(state_name, new_state); ret=0; goto release_and_exit; } else { ret=4; goto release_and_exit; } } else if (PL_strcmp(new_state, "Writing")==0) { if (PL_strcmp(cur_state, "Disabled") == 0) { // Disabled -> Writing (admin start to write changes - need to save writer) RA::GetConfigStore()->Add(writer_name, me); RA::GetConfigStore()->Add(state_name, new_state); ret=0; goto release_and_exit; } if ((!agent_must_approve(type)) && (PL_strcmp(cur_state, "Enabled") == 0)) { // Enabled -> Writing (admin start to write changes for case where agent need not approve - need to save writer) RA::GetConfigStore()->Add(writer_name, me); RA::GetConfigStore()->Add(state_name, new_state); ret=0; goto release_and_exit; } else { ret=5; goto release_and_exit; } } } if (PL_strcmp(who, "Agent")==0) { if (PL_strcmp(new_state, "Disabled")==0) { if ((PL_strcmp(cur_state, "Enabled") == 0) || (PL_strcmp(cur_state, "Pending_Approval") == 0)) { // "Enabled or Pending" to "Disabled", agent disables or rejects RA::GetConfigStore()->Add(state_name, new_state); ret=0; goto release_and_exit; } else { ret=6; goto release_and_exit; } } else if (PL_strcmp(new_state, "Enabled")==0) { if ((PL_strcmp(cur_state, "Disabled") == 0) || (PL_strcmp(cur_state, "Pending_Approval") == 0)) { // "Disabled or Pending" to "Enabled", agent approves RA::GetConfigStore()->Add(state_name, new_state); ret=0; goto release_and_exit; } else { ret=7; goto release_and_exit; } } else if (PL_strcmp(new_state, "Pending_Approval")==0) { // no valid transitions for agent ret=8; goto release_and_exit; } else if (PL_strcmp(new_state, "Writing")==0) { // no valid transitions for agent ret=9; goto release_and_exit; } } release_and_exit: PR_Unlock(config_lock); //audit changes char pString[256]=""; char msg[256] = ""; if (PL_strcmp(new_ts, "") != 0) { PR_snprintf(pString, 256, "%s;;%s+%s;;%s", state_name, final_state, ts_name, new_ts); PR_snprintf(msg, 256, "config item state and timestamp changed"); } else { PR_snprintf(pString, 256, "%s;;%s", state_name, final_state); PR_snprintf(msg, 256, "config item state changed"); } if (ret == 0) { RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, who, "Success", type, pString, msg); } else { PR_snprintf(msg, 256, "config item state or timestamp change failed, return value is %d", ret); RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, who, "Failure", type, pString, msg); } return ret; } /** * takes in the type and name of the parameter set * looks up the regular expression pattern for this parameter set in CS.cfg and substitutes * $name with the name of the parameter set. * returns this "fixed" pattern as a string (that must be freed by caller) **/ char *get_fixed_pattern(char *ptype, char *pname) { char configname[256]=""; char tmpc[256]=""; char *p = NULL; char *fixed_pattern = NULL; PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype ); const char* pattern = RA::GetConfigStore()->GetConfigAsString( configname ); if (pattern == NULL) { tokendbDebug("get_pattern_substore: pattern is NULL"); return NULL; } if ((p = PL_strstr(pattern, "$name"))) { PL_strncpy(tmpc, pattern, p-pattern); tmpc[p-pattern] = '\0'; sprintf(tmpc+(p-pattern), "%s%s", pname, p+PL_strlen("$name")); fixed_pattern = (char *) PL_strdup(tmpc); p = NULL; } else { fixed_pattern=PL_strdup(pattern); } tokendbDebug(fixed_pattern); return fixed_pattern; } /** * get ConfigStore with entries that match the relevant pattern * must be freed by caller **/ ConfigStore *get_pattern_substore(char *ptype, char *pname) { char *fixed_pattern = NULL; ConfigStore *store = NULL; fixed_pattern=get_fixed_pattern(ptype, pname); if (fixed_pattern == NULL) { return NULL; } store = RA::GetConfigStore()->GetPatternSubStore(fixed_pattern); do_strfree(fixed_pattern); return store; } /*** * parse the parameter string of form foo=bar&&foo2=baz&& ... * and perform (and audit) the changes **/ void parse_and_apply_changes(char* userid, char* ptype, char* pname, const char *operation, char *params) { char *pair; char *line = NULL; int i; int len; char *lasts = NULL; int op=0; char audit_str[4096] = ""; char *fixed_pattern = NULL; regex_t *regex=NULL; int err_no; if (PL_strstr(operation, "ADD")) { op=1; } else if (PL_strstr(operation, "DELETE")) { op=2; } else if (PL_strstr(operation, "MODIFY")) { op=3; } tokendbDebug(operation); // get the correct pattern and regex fixed_pattern = get_fixed_pattern(ptype, pname); if (fixed_pattern == NULL) { tokendbDebug("parse_and_apply_changes: pattern is NULL. Aborting changes .."); return; } regex = (regex_t *) malloc(sizeof(regex_t)); memset(regex, 0, sizeof(regex_t)); if((err_no=regcomp(regex, fixed_pattern, 0))!=0) /* Comple the regex */ { // Error in computing the regex size_t length; char *buffer; length = regerror (err_no, regex, NULL, 0); buffer = (char *) PR_Malloc(length); regerror (err_no, regex, buffer, length); tokendbDebug("parse_and_apply_changes: error computing the regex, aborting changes"); tokendbDebug(buffer); PR_Free(buffer); regfree(regex); return; } size_t no_sub = regex->re_nsub+1; regmatch_t *result = NULL; line = PL_strdup(params); pair = PL_strtok_r(line, "&&", &lasts); while (pair != NULL) { len = strlen(pair); i = 0; while (1) { if (i >= len) { goto skip1; } if (pair[i] == '\0') { goto skip1; } if (pair[i] == '=') { pair[i] = '\0'; break; } i++; } result = NULL; result = (regmatch_t *) PR_Malloc(sizeof(regmatch_t) * no_sub); if (regexec(regex, (char *) &pair[0], no_sub, result, 0)!=0) { tokendbDebug("parse_and_apply_changes: parameter does not match pattern. Dropping edit .."); tokendbDebug(&pair[0]); if (result != NULL) { PR_Free(result); result=NULL; } goto skip1; } if (result != NULL) { PR_Free(result); result=NULL; } if (op == 1) { //ADD RA::GetConfigStore()->Add(&pair[0], &pair[i+1]); PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]); RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter added"); } else if (op == 2) { //DELETE RA::GetConfigStore()->Remove(&pair[0]); PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]); RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter deleted"); } else if (op == 3) { //MODIFY RA::GetConfigStore()->Add(&pair[0], &pair[i+1]); PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]); RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter modified"); } skip1: pair = PL_strtok_r(NULL, "&&", &lasts); } do_strfree(line); do_strfree(fixed_pattern); } static int get_time_limit(char *query) { char *val = NULL; int ret; val = get_field(query, "timeLimit=", SHORT_LEN); if (val == NULL) { return maxTimeLimit; } ret = atoi(val); if ((ret == 0) || (ret > maxTimeLimit)) { return maxTimeLimit; } return ret; } static int get_size_limit(char *query) { char *val = NULL; int ret; val = get_field(query, "sizeLimit=", SHORT_LEN); if (val == NULL) { return maxSizeLimit; } ret = atoi(val); if ((ret == 0) || (ret > maxSizeLimit)) { return maxSizeLimit; } return ret; } /** * generate a simple password of at least specified length * containing upper case, lower case and special characters */ #define PW_MAX_LEN 1024 static char *generatePassword(int length) { char choices[80] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*_-+=':;.,"; bool pw_ok = false; int i=0; int upper=0, lower=0, number=0, special=0; char pw[PW_MAX_LEN] = ""; srand(time(0)); while (!pw_ok) { int x; x = 0 + int(79.0 * rand()/(RAND_MAX+1.0)); pw[i] = choices[x]; if (isupper(choices[x])) upper ++; if (islower(choices[x])) lower ++; if (isdigit(choices[x])) number ++; if (! isalpha(choices[x])) special ++; if ((i >= length) && (upper >=2) && (lower >=2) && (special >=2) && (number >=2)) pw_ok = true; i++; if (i == PW_MAX_LEN) { i=0; upper = 0; lower = 0; special =0; number =0; PR_snprintf(pw, PW_MAX_LEN, ""); } } return PL_strdup(pw); } /** * mod_tokendb_handler handles the protocol between the tokendb and the RA */ static int mod_tokendb_handler( request_rec *rq ) { int sendPieces = 0; int rc = 0; LDAPMessage *result = NULL; LDAPMessage *e = NULL; LDAPMod **mods = NULL; char *injection = NULL; char *mNum = NULL; char *buf = NULL; char *uri = NULL; char *query = NULL; char *cert = NULL; char *base64_cert = NULL; char *userid = NULL; char *error = NULL; char *tid = NULL; char *question = NULL; const char *tokentype = NULL; /* user fields */ char *uid = NULL; char *firstName = NULL; char *lastName = NULL; char *opOperator = NULL; char *opAdmin = NULL; char *opAgent = NULL; char *userCert = NULL; /* keep track of which menu we are in - operator or agent */ char *topLevel = NULL; char **attrs = NULL; char **vals = NULL; struct berval **bvals = NULL; int maxReturns; int q; int i, n, len, nEntries, entryNum; int status = LDAP_SUCCESS; int size, tagOffset, statusNum; char fixed_injection[MAX_INJECTION_SIZE]; char pString[512] = ""; char oString[512] = ""; char pLongString[4096] = ""; char configname[512] =""; char filter[512] = ""; char msg[512] = ""; char question_no[100] =""; char cuid[256] = ""; char cuidUserId[100]=""; char tokenStatus[100]=""; char tokenReason[100]=""; int token_ui_state= 0; bool show_token_ui_state = false; char serial[100]=""; char userCN[256]=""; char tokenType[512]=""; apr_table_t *post = NULL; /* used for POST data */ char *statusString = NULL; char *s1, *s2; char *end; struct berval **attr_values = NULL; char *auth_filter = NULL; /* authorization */ int is_admin = 0; int is_agent = 0; int is_operator = 0; int end_val =0; int start_val = 0; /* current operation for audit */ char *op = NULL; RA::Debug( "mod_tokendb_handler::mod_tokendb_handler", "mod_tokendb_handler::mod_tokendb_handler" ); RA::Debug( "mod_tokendb::mod_tokendb_handler", "uri '%s'", rq->uri); /* XXX: We need to change "tus" to "tokendb" */ if (strcmp(rq->handler, "tus") != 0) { RA::Debug( "mod_tokendb::mod_tokendb_handler", "DECLINED uri '%s'", rq->uri); return DECLINED; } RA::Debug( "mod_tokendb::mod_tokendb_handler", "uri '%s' DONE", rq->uri); tokendbDebug( "tokendb request arrived...serving tokendb\n" ); injection = fixed_injection; ap_set_content_type( rq, "text/html" ); if( !is_tus_db_initialized() ) { tokendbDebug( "token DB was not initialized \n" ); if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) { if( error != NULL ) { PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s", JS_START, "var error = \"", error, "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); PR_smprintf_free( error ); error = NULL; } else { PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s", JS_START, "var error = \"", "NULL", "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); } if( buf != NULL ) { PR_Free( buf ); buf = NULL; } return DONE; } } else { tokendbDebug( "token DB was initialized\n" ); } tokendbDebug( "authentication\n" ); cert = nss_var_lookup( rq->pool, rq->server, rq->connection, rq, ( char * ) "SSL_CLIENT_CERT" ); if( cert == NULL ) { error_out("Authentication Failure", "Failed to authenticate request"); RA::Audit(EV_AUTH_FAIL, AUDIT_MSG_AUTH, "null", "null", "Failure", "authentication failure, no cert"); do_free(buf); return DONE; } tokendbDebug( cert ); tokendbDebug( "\n" ); base64_cert = stripBase64HeaderAndFooter( cert ); tokendbDebug( base64_cert ); tokendbDebug( "\n" ); userid = tus_authenticate( base64_cert ); if( userid == NULL ) { error_out("Authentication Failure", "Failed to authenticate request"); SECStatus rv; SECItem certDER; CERTCertificate *c = NULL; rv = ATOB_ConvertAsciiToItem(&certDER, base64_cert); if (rv) { RA::Debug("mod_tokendb_handler::mod_tokendb_handler", "Error converting certificate data to binary"); } else { c = CERT_DecodeCertFromPackage((char *)certDER.data, certDER.len); } RA::Audit(EV_AUTH_FAIL, AUDIT_MSG_AUTH, (c!= NULL) && (c->subjectName != NULL) ? c->subjectName : "null", "null", "Failure", "authentication failure"); do_free(buf); if (c != NULL) { CERT_DestroyCertificate(c); } return DONE; } do_free(base64_cert); // useful to indicate cn of user cert RA::Audit(EV_AUTH_SUCCESS, AUDIT_MSG_AUTH, userid, userid, "Success", "authentication success"); /* authorization */ is_admin = tus_authorize(TOKENDB_ADMINISTRATORS_IDENTIFIER, userid); if (is_admin) { RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Admin", "Success", "assume privileged role"); } is_agent = tus_authorize(TOKENDB_AGENTS_IDENTIFIER, userid); if (is_agent) { RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Agent", "Success", "assume privileged role"); } is_operator = tus_authorize(TOKENDB_OPERATORS_IDENTIFIER, userid); if (is_operator) { RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Operator", "Success", "assume privileged role"); } if( rq->uri != NULL ) { uri = PL_strdup( rq->uri ); } if (rq->method_number == M_POST) { status = read_post(rq, &post); if(post && !apr_is_empty_table(post)) { query = PL_strdup( apr_table_get(post, "query")); } } else { /* GET request */ if( rq->args != NULL ) { query = PL_strdup( rq->args ); } } RA::Debug( "mod_tokendb_handler::mod_tokendb_handler", "uri='%s' params='%s'", uri, ( query==NULL?"":query ) ); if( query == NULL ) { char *itemplate = NULL; tokendbDebug( "authorization for index case\n" ); if (is_agent) { itemplate = indexTemplate; } else if (is_operator) { itemplate = indexOperatorTemplate; } else if (is_admin) { itemplate = indexAdminTemplate; } else { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var agent_target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n", "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n" ); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( itemplate, injection ); itemplate = NULL; } else if( ( PL_strstr( query, "op=index_operator" ) ) ) { tokendbDebug( "authorization for op=index_operator\n" ); if (!is_operator) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index_operator", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index_operator", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n" ); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( indexOperatorTemplate, injection ); } else if( ( PL_strstr( query, "op=index_admin" ) ) ) { tokendbDebug( "authorization\n" ); if (!is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index_admin", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index_admin", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n" ); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( indexAdminTemplate, injection ); } else if( ( PL_strstr( query, "op=do_token" ) ) ) { tokendbDebug( "authorization for do_token\n" ); if( !is_agent ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "do_token", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "do_token", "Success", "Tokendb user authorization"); /* XXX - chrisho */ /* op=do_token */ /* question=1|2|... */ /* tid=cuid */ tokendbDebug( "print query\n" ); tokendbDebug( query ); tokendbDebug( "\n" ); tid = PL_strstr( query, "tid=" ); if( tid != NULL ) { end = PL_strchr( tid, '&' ); if( end != NULL ) { i = end - tid - 4; if( i > 0 ) { memcpy( cuid, tid+4, i ); } cuid[i] = '\0'; } else { PL_strcpy( cuid, tid+4 ); } } tokendbDebug( "cuid:" ); tokendbDebug( cuid ); tokendbDebug( "\n" ); question = PL_strstr( query, "question=" ); q = question[9] - '0'; PR_snprintf( question_no, 256, "%d", q ); tokendbDebug( "question_no:" ); tokendbDebug( question_no ); rc = find_tus_db_entry( cuid, 1, &result ); if( rc == 0 ) { e = get_first_entry( result ); if( e != NULL ) { attr_values = get_attribute_values( e, "tokenUserID" ); tokendbDebug( "cuidUserId:" ); if (valid_berval(attr_values)) { PL_strcpy( cuidUserId, attr_values[0]->bv_val ); tokendbDebug( cuidUserId ); free_values(attr_values, 1); attr_values = NULL; } else tokendbDebug("null"); attr_values = get_attribute_values( e, "tokenType" ); tokendbDebug( "tokenType:" ); if (valid_berval(attr_values)) { PL_strcpy( tokenType, attr_values[0]->bv_val ); tokendbDebug( tokenType ); free_values(attr_values, 1); attr_values = NULL; } else tokendbDebug("null"); attr_values = get_attribute_values( e, "tokenStatus" ); tokendbDebug( "tokenStatus:" ); if (valid_berval(attr_values)) { PL_strcpy( tokenStatus, attr_values[0]->bv_val ); tokendbDebug( tokenStatus ); free_values(attr_values, 1); attr_values = NULL; } else tokendbDebug("null"); attr_values = get_attribute_values( e, "tokenReason" ); tokendbDebug( "tokenReason:" ); if (valid_berval(attr_values)) { PL_strcpy( tokenReason, attr_values[0]->bv_val ); tokendbDebug( tokenReason ); free_values(attr_values, 1); attr_values = NULL; } else tokendbDebug("null"); } } if( result != NULL ) { ldap_msgfree( result ); } token_ui_state = get_token_ui_state(tokenStatus, tokenReason); /* Is this token physically damaged */ if(( q == 1 ) && (transition_allowed(token_ui_state, 1))) { PR_snprintf((char *)msg, 256, "'%s' marked token physically damaged", userid); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "initiated", msg, cuidUserId, tokenType); /* get the certificates on this lost token */ PR_snprintf( ( char * ) filter, 256, "(&(tokenID=%s)(tokenUserID=%s))", cuid, cuidUserId ); rc = find_tus_certificate_entries_by_order_no_vlv( filter, &result, 1 ); if( rc == 0 ) { CertEnroll *certEnroll = new CertEnroll(); for( e = get_first_entry( result ); e != NULL; e = get_next_entry( e ) ) { char *attr_status = get_cert_status( e ); if( strcmp( attr_status, "revoked" ) == 0 ) { if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } continue; } char *attr_serial= get_cert_serial( e ); char *attr_tokenType = get_cert_tokenType( e ); char *attr_keyType = get_cert_type( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "destroyed.revokeCert", attr_tokenType, attr_keyType ); bool revokeCert = RA::GetConfigStore()-> GetConfigAsBool( configname, true ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "destroyed.revokeCert.reason", attr_tokenType, attr_keyType ); char *revokeReason = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname, "0" ) ); if( revokeCert ) { char *attr_cn = get_cert_cn( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.ca.conn", attr_tokenType, attr_keyType ); char *connid = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname ) ); PR_snprintf( serial, 100, "0x%s", attr_serial ); statusNum = certEnroll->RevokeCertificate(revokeReason, serial, connid, statusString ); if (statusNum != 0) { // revocation errors if( strcmp( revokeReason, "6" ) == 0 ) { PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "revoked_on_hold", serial, connid, statusString); } else { PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "revoke", serial, connid, statusString); } } else { // update certificate status if( strcmp( revokeReason, "6" ) == 0 ) { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "revoked_on_hold" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "revoked_on_hold", serial, connid, ""); } else { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "revoked" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "revoke", serial, connid, ""); } } if( attr_cn != NULL ) { PL_strfree( attr_cn ); attr_cn = NULL; } do_free(statusString); } if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } if( attr_serial != NULL ) { PL_strfree( attr_serial ); attr_serial = NULL; } if( attr_tokenType != NULL ) { PL_strfree( attr_tokenType ); attr_tokenType = NULL; } if( attr_keyType != NULL ) { PL_strfree( attr_keyType ); attr_keyType = NULL; } } if( result != NULL ) { ldap_msgfree( result ); } if( certEnroll != NULL ) { delete certEnroll; certEnroll = NULL; } } /* change the tokenStatus to lost (reason: destroyed). */ rc = update_token_status_reason( cuidUserId, cuid, "lost", "destroyed" ); if( rc == -1 ) { tokendbDebug( "token is physically damaged. rc = -1\n" ); PR_snprintf(oString, 512, "token_id;;%s", cuid); PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed"); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked physically damaged, rc=-1"); PR_snprintf((char *)msg, 256, "Failed to update token status as physically damaged"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s", JS_START, "var error = \"Failed to create LDAPMod: ", "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "Failed to create LDAPMod" ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } else if( rc > 0 ) { tokendbDebug( "token is physically damaged. rc > 0\n" ); PR_snprintf(oString, 512, "token_id;;%s", cuid); PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed"); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked physically damaged, rc>0"); PR_snprintf((char *)msg, 256, "Failed to update token status as physically damaged"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s", JS_START, "var error = \"LDAP mod error: ", ldap_err2string( rc ), "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "LDAP error: %s", ldap_err2string( rc ) ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } PR_snprintf(oString, 512, "token_id;;%s", cuid); PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed"); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked physically damaged"); PR_snprintf((char *)msg, 256, "Token marked as physically damaged"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, tokenType); /* Is this token permanently lost? */ } else if(((q == 2) && (transition_allowed(token_ui_state, 2))) || ((q == 6) && (transition_allowed(token_ui_state, 6)))) { if (q == 2) { PR_snprintf((char *)msg, 256, "'%s' marked token permanently lost", userid); } else { PR_snprintf((char *)msg, 256, "'%s' marked token terminated", userid); } RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "initiated", msg, cuidUserId, tokenType); /* get the certificates on this lost token */ PR_snprintf( ( char * ) filter, 256, "(&(tokenID=%s)(tokenUserID=%s))", cuid, cuidUserId ); rc = find_tus_certificate_entries_by_order_no_vlv( filter, &result, 1 ); if( rc == 0 ) { CertEnroll *certEnroll = new CertEnroll(); for( e = get_first_entry( result ); e != NULL; e = get_next_entry( e ) ) { char *attr_status = get_cert_status( e ); if( strcmp( attr_status, "revoked" ) == 0 ) { if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } continue; } char *attr_serial= get_cert_serial( e ); char *attr_tokenType = get_cert_tokenType( e ); char *attr_keyType = get_cert_type( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "keyCompromise.revokeCert", attr_tokenType, attr_keyType ); bool revokeCert = RA::GetConfigStore()-> GetConfigAsBool( configname, true ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "keyCompromise.revokeCert.reason", attr_tokenType, attr_keyType ); char *revokeReason = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname, "1" ) ); if( revokeCert ) { char *attr_cn = get_cert_cn( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.ca.conn", attr_tokenType, attr_keyType ); char *connid = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname ) ); PR_snprintf( serial, 100, "0x%s", attr_serial ); statusNum = certEnroll-> RevokeCertificate( revokeReason, serial, connid, statusString ); if (statusNum != 0) { // revocation errors if( strcmp( revokeReason, "6" ) == 0 ) { PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "revoked_on_hold", serial, connid, statusString); } else { PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "revoke", serial, connid, statusString); } } else { // update certificate status if( strcmp( revokeReason, "6" ) == 0 ) { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "revoked_on_hold" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "revoked_on_hold", serial, connid, ""); } else { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "revoked" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "revoke", serial, connid, ""); } } if( attr_cn != NULL ) { PL_strfree( attr_cn ); attr_cn = NULL; } do_free(statusString); } if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } if( attr_serial != NULL ) { PL_strfree( attr_serial ); attr_serial = NULL; } if( attr_tokenType != NULL ) { PL_strfree( attr_tokenType ); attr_tokenType = NULL; } if( attr_keyType != NULL ) { PL_strfree( attr_keyType ); attr_keyType = NULL; } } if( result != NULL ) { ldap_msgfree( result ); } if( certEnroll != NULL ) { delete certEnroll; certEnroll = NULL; } } /* revoke all the certs on the token. make http connection to CA */ /* change the tokenStatus to lost (reason: keyCompromise) */ tokendbDebug( "Revoke all the certs on this token " "(reason: keyCompromise)\n" ); PR_snprintf(oString, 512, "token_id;;%s", cuid); if (q == 6) { /* terminated */ PR_snprintf(pString, 512, "tokenStatus;;terminated+tokenReason;;keyCompromise"); rc = update_token_status_reason( cuidUserId, cuid, "terminated", "keyCompromise" ); } else { PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;keyCompromise"); rc = update_token_status_reason( cuidUserId, cuid, "lost", "keyCompromise" ); } if( rc == -1 ) { if (q == 6) { /* terminated*/ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked terminated, rc=-1"); PR_snprintf((char *)msg, 256, "Failure in updating token status to terminated"); } else { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked permanently lost, rc=-1"); PR_snprintf((char *)msg, 256, "Failure in updating token status to permanently lost"); } RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s", JS_START, "var error = \"Failed to create LDAPMod: ", "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "Failed to create LDAPMod" ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } else if( rc > 0 ) { if (q == 6) { /* terminated*/ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked terminated, rc=>0"); PR_snprintf((char *)msg, 256, "Failure in updating token status to terminated"); } else { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked permanently lost, rc>0"); PR_snprintf((char *)msg, 256, "Failure in updating token status to permanently lost"); } RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s", JS_START, "var error = \"LDAP mod error: ", ldap_err2string( rc ), "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "LDAP error: %s", ldap_err2string( rc ) ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } if (q == 6) { /* terminated*/ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked terminated"); PR_snprintf((char *)msg, 256, "Token marked terminated"); } else { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked permanently lost"); PR_snprintf((char *)msg, 256, "Token marked permanently lost"); } RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, tokenType); /* Is this token temporarily lost? */ } else if(( q == 3 ) && (transition_allowed(token_ui_state, 3))) { bool revocation_errors = false; PR_snprintf((char *)msg, 256, "'%s' marked token temporarily lost", userid); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "initiated", msg, cuidUserId, tokenType); /* all certs on the token are revoked (onHold) */ tokendbDebug( "Revoke all the certs on this token " "(reason: onHold)\n" ); /* get the certificates on this lost token */ PR_snprintf( ( char * ) filter, 256, "(&(tokenID=%s)(tokenUserID=%s))", cuid, cuidUserId ); rc = find_tus_certificate_entries_by_order_no_vlv( filter, &result, 1 ); if( rc == 0 ) { CertEnroll *certEnroll = new CertEnroll(); for( e = get_first_entry( result ); e != NULL; e = get_next_entry( e ) ) { char *attr_status = get_cert_status( e ); if( strcmp( attr_status, "revoked" ) == 0 || strcmp( attr_status, "revoked_on_hold" ) == 0 ) { if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } continue; } char *attr_serial= get_cert_serial( e ); char *attr_tokenType = get_cert_tokenType( e ); char *attr_keyType = get_cert_type( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "onHold.revokeCert", attr_tokenType, attr_keyType ); bool revokeCert = RA::GetConfigStore()-> GetConfigAsBool( configname, true ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery.onHold." "revokeCert.reason", attr_tokenType, attr_keyType ); char *revokeReason = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname, "0" ) ); if( revokeCert ) { char *attr_cn = get_cert_cn( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.ca.conn", attr_tokenType, attr_keyType ); char *connid = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname ) ); PR_snprintf( serial, 100, "0x%s", attr_serial ); statusNum = certEnroll-> RevokeCertificate( revokeReason, serial, connid, statusString ); if (statusNum != 0) { // revocation errors if( strcmp( revokeReason, "6" ) == 0 ) { PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "revoked_on_hold", serial, connid, statusString); } else { PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "revoke", serial, connid, statusString); } revocation_errors = true; } else { // update certificate status if( strcmp( revokeReason, "6" ) == 0 ) { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "revoked_on_hold" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "revoked_on_hold", serial, connid, ""); } else { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "revoked" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "revoke", serial, connid, ""); } } do_free(statusString); } if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } if( attr_serial != NULL ) { PL_strfree( attr_serial ); attr_serial = NULL; } if( attr_tokenType != NULL ) { PL_strfree( attr_tokenType ); attr_tokenType = NULL; } if( attr_keyType != NULL ) { PL_strfree( attr_keyType ); attr_keyType = NULL; } } if (result != NULL) { ldap_msgfree( result ); } if( certEnroll != NULL ) { delete certEnroll; certEnroll = NULL; } } PR_snprintf(oString, 512, "token_id;;%s", cuid); PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;onHold"); if (revocation_errors) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost failed, failed to revoke certificates"); PR_snprintf((char *)msg, 256, "Failed to revoke certificates"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); error_out("Errors in revoking certificates.", "Errors in revoking certificates."); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } rc = update_token_status_reason( cuidUserId, cuid, "lost", "onHold" ); if( rc == -1 ) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost, rc=-1"); PR_snprintf((char *)msg, 256, "Failed to update token status as temporarily lost"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s", JS_START, "var error = \"Failed to create LDAPMod: ", "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "Failed to create LDAPMod" ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } else if( rc > 0 ) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost, rc>0"); PR_snprintf((char *)msg, 256, "Failed to update token status as temporarily lost"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s", JS_START, "var error = \"LDAP mod error: ", ldap_err2string( rc ), "\";\n", JS_STOP ); buf = getData( errorTemplate, injection ); ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "LDAP error: %s", ldap_err2string( rc ) ); ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq ); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked temporarily lost"); PR_snprintf((char *)msg, 256, "Token marked temporarily lost"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, tokenType); /* Is this temporarily lost token found? */ } else if(( q == 4 ) && ( transition_allowed(token_ui_state, 4) )) { PR_snprintf((char *)msg, 256, "'%s' marked lost token found", userid); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "initiated", msg, cuidUserId, tokenType); tokendbDebug( "The temporarily lost token is found.\n" ); // to find out the tokenType on this lost token PR_snprintf( ( char * ) filter, 256, "(&(tokenID=%s)(tokenUserID=%s))", cuid, cuidUserId ); /* all certs on the token are unrevoked (offHold) */ /* get the certificates on this lost token */ tokendbDebug( "Offhold all the certificates on " "the temp lost token." ); rc = find_tus_certificate_entries_by_order_no_vlv( filter, &result, 1 ); if( rc == 0 ) { CertEnroll *certEnroll = new CertEnroll(); for( e = get_first_entry( result ); e != NULL; e = get_next_entry( e ) ) { char *attr_status = get_cert_status( e ); if( strcmp( attr_status, "active" ) == 0 || strcmp( attr_status, "revoked" ) == 0 ) { if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } continue; } char *attr_serial= get_cert_serial( e ); char *attr_tokenType = get_cert_tokenType( e ); char *attr_keyType = get_cert_type( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "onHold.revokeCert", attr_tokenType, attr_keyType ); bool revokeCert = RA::GetConfigStore()-> GetConfigAsBool( configname, true ); if( revokeCert ) { char *attr_cn = get_cert_cn( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.ca.conn", attr_tokenType, attr_keyType ); char *connid = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname ) ); PR_snprintf( serial, 100, "0x%s", attr_serial ); int statusNum = certEnroll-> UnrevokeCertificate( serial, connid, statusString ); if (statusNum == 0) { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as active", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "active" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "unrevoke", serial, connid, ""); } else { PR_snprintf((char *)msg, 256, "Errors in unrevoking Certificate '%s': %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "unrevoke", serial, connid, statusString); } if( attr_cn != NULL ) { PL_strfree( attr_cn ); attr_cn = NULL; } do_free(statusString); } if( attr_serial != NULL ) { PL_strfree( attr_serial ); attr_serial = NULL; } if( attr_tokenType != NULL ) { PL_strfree( attr_tokenType ); attr_tokenType = NULL; } if( attr_keyType != NULL ) { PL_strfree( attr_keyType ); attr_keyType = NULL; } } // end of for loop if( result != NULL ) { ldap_msgfree( result ); } if( certEnroll != NULL ) { delete certEnroll; certEnroll = NULL; } } update_token_status_reason( cuidUserId, cuid, "active", NULL ); PR_snprintf(oString, 512, "token_id;;%s", cuid); PR_snprintf(pString, 512, "tokenStatus;;active+tokenReason;;null"); if( rc == -1 ) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "lost token marked found, rc=-1"); PR_snprintf((char *)msg, 256, "Failed to update lost token status as found"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); error_out("Failed to create LDAPMod: ", "Failed to create LDAPMod"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } else if( rc > 0 ) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "lost token marked found, rc>0"); PR_snprintf((char *)msg, 256, "Failed to update lost token status as found"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, tokenType); ldap_error_out("LDAP mod error: ", "LDAP error: %s"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "lost token marked found"); PR_snprintf((char *)msg, 256, "Lost token marked found"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, tokenType); /* Does this temporarily lost token become permanently lost? */ } else if ( (q == 5) && (transition_allowed(token_ui_state, 5)) ) { PR_snprintf((char *)msg, 256, "'%s' marked lost token permanently lost", userid); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "initiated", msg, cuidUserId, tokenType); tokendbDebug( "Change the revocation reason from onHold " "to keyCompromise\n" ); // to find out the tokenType on this lost token PR_snprintf( ( char * ) filter, 256, "(&(tokenID=%s)(tokenUserID=%s))", cuid, cuidUserId ); /* revoke all the certs on this token (reason: keyCompromise) */ tokendbDebug( "Revoke all the certs on this token " "(reason: keyCompromise)\n" ); /* get the certificates on this lost token */ PR_snprintf( ( char * ) filter, 256, "(&(tokenID=%s)(tokenUserID=%s))", cuid, cuidUserId ); rc = find_tus_certificate_entries_by_order_no_vlv( filter, &result, 1 ); if( rc == 0 ) { CertEnroll *certEnroll = new CertEnroll(); for( e = get_first_entry(result); e != NULL; e = get_next_entry( e ) ) { char *attr_status = get_cert_status( e ); if( strcmp( attr_status, "revoked" ) == 0 ) { if( attr_status != NULL ) { PL_strfree( attr_status ); attr_status = NULL; } continue; } char *attr_serial= get_cert_serial( e ); char *attr_tokenType = get_cert_tokenType( e ); char *attr_keyType = get_cert_type( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "keyCompromise.revokeCert", attr_tokenType, attr_keyType ); bool revokeCert = RA::GetConfigStore()-> GetConfigAsBool( configname, true ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.recovery." "keyCompromise.revokeCert.reason", attr_tokenType, attr_keyType ); char *revokeReason = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname, "1" ) ); if( revokeCert ) { char *attr_cn = get_cert_cn( e ); PR_snprintf( ( char * ) configname, 256, "op.enroll.%s.keyGen.%s.ca.conn", attr_tokenType, attr_keyType ); char *connid = ( char * ) ( RA::GetConfigStore()-> GetConfigAsString( configname ) ); PR_snprintf( serial, 100, "0x%s", attr_serial ); int statusNum = 0; if(( strcmp( attr_status, "revoked_on_hold" ) == 0 ) && (strcmp(revokeReason, "6" ) != 0)) { statusNum = certEnroll-> UnrevokeCertificate( serial, connid, statusString ); if (statusNum == 0) { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as active", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "initiated", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "active" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "unrevoke", serial, connid, ""); do_free(statusString); statusNum = certEnroll-> RevokeCertificate( revokeReason, serial, connid, statusString ); if (statusNum == 0) { PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType); update_cert_status( attr_cn, "revoked" ); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Success", "revoke", serial, connid, ""); } else { PR_snprintf((char *)msg, 256, "Errors in revoking Certificate '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "revoke", serial, connid, statusString); } } else { PR_snprintf((char *)msg, 256, "Errors in unrevoking Certificate '%s' : %s", attr_cn, statusString); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid, "Failure", "unrevoke", serial, connid, statusString); } do_free(statusString); } if( attr_cn != NULL ) { PL_strfree( attr_cn ); attr_cn = NULL; } } if( attr_serial != NULL ) { PL_strfree( attr_serial ); attr_serial = NULL; } if( attr_tokenType != NULL ) { PL_strfree( attr_tokenType ); attr_tokenType = NULL; } if( attr_keyType != NULL ) { PL_strfree( attr_keyType ); attr_keyType = NULL; } } // end of the for loop if( result != NULL ) { ldap_msgfree( result ); } if( certEnroll != NULL ) { delete certEnroll; certEnroll = NULL; } } rc = update_token_status_reason( cuidUserId, cuid, "lost", "keyCompromise" ); PR_snprintf(oString, 512, "token_id;;%s", cuid); PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;keyCompromise"); RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "lost token marked permanently lost"); PR_snprintf((char *)msg, 256, "Lost token marked permanently lost"); RA::tdb_activity(rq->connection->client_ip, cuid, "do_token", "success", msg, cuidUserId, tokenType); } else { // invalid operation or transition error_out("Transition or operation not allowed", "Transition or operation not allowed"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } tokendbDebug( "do_token: rc = 0\n" ); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%d%s%s%s%s%s%s%s", JS_START, "var rc = \"", rc, "\";\n", "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n" ); add_allowed_token_transitions(token_ui_state, injection); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( doTokenTemplate, injection ); /* currently not used - alee } else if( ( PL_strstr( query, "op=revoke" ) ) ) { tokendbDebug("authorization\n"); if( ! is_agent ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "revoke", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "revoke", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n" ); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( revokeTemplate, injection ); */ } else if( ( PL_strstr( query, "op=search_activity_admin" ) ) ) { tokendbDebug( "authorization\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_activity_admin", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_activity_admin", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n" ); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( searchActivityAdminTemplate, injection ); } else if( ( PL_strstr( query, "op=search_activity" ) ) ) { tokendbDebug( "authorization\n" ); if ((! is_agent) && (! is_operator)) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_activity", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_activity", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n" ); topLevel = get_field(query, "top=", SHORT_LEN); if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) { PL_strcat(injection, "var topLevel = \"operator\";\n"); } do_free(topLevel); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( searchActivityTemplate, injection ); } else if( ( PL_strstr( query, "op=search_admin" ) ) || ( PL_strstr( query, "op=search_users" ) )) { tokendbDebug( "authorization\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_admin,search_users", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_admin,search_users", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n" ); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); if ( PL_strstr( query, "op=search_admin" ) ) { buf = getData( searchAdminTemplate, injection ); } else if ( PL_strstr( query, "op=search_users" ) ) { buf = getData( searchUserTemplate, injection ); } } else if ( PL_strstr( query, "op=search_certificate" ) ) { tokendbDebug( "authorization\n" ); if ((! is_agent) && (! is_operator)) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_certificate", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_certificate", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n"); topLevel = get_field(query, "top=", SHORT_LEN); if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) { PL_strcat(injection, "var topLevel = \"operator\";\n"); } do_free(topLevel); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( searchCertificateTemplate, injection ); } else if( ( PL_strstr( query, "op=search" ) ) ) { tokendbDebug( "authorization for op=search\n" ); if ((! is_agent) && (! is_operator)) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n"); topLevel = get_field(query, "top=", SHORT_LEN); if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) { PL_strcat(injection, "var topLevel = \"operator\";\n"); } do_free(topLevel); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( searchTemplate, injection ); } else if( ( PL_strstr( query, "op=new" ) ) ) { tokendbDebug( "authorization\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "new", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "new", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n" ); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( newTemplate,injection ); } else if ( ( PL_strstr( query, "op=add_user" ) ) ) { tokendbDebug( "authorization for add_user\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_user", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_user", "Success", "Tokendb user authorization"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( newUserTemplate,injection ); } else if ( ( PL_strstr( query, "op=confirm_delete_config" ) ) ) { tokendbDebug( "authorization for confirm_delete_config\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "confirm_delete_config", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "confirm_delete_config", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *ptimestamp = NULL; char *pvalues = NULL; char *large_injection = NULL; char *pstate = NULL; char *disp_conf_type = NULL; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); pstate = get_post_field(post, "pstate", SHORT_LEN); ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN); pvalues = get_post_field_s(post, "pvalues"); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype ); disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); large_injection = (char *) PR_Malloc(PL_strlen(pvalues) + MAX_INJECTION_SIZE); PR_snprintf( large_injection, PL_strlen(pvalues) + MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", ptype, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_name = \"", pname, "\";\n", "var conf_state = \"", pstate, "\";\n", "var conf_tstamp = \"", ptimestamp, "\";\n", "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n", "var conf_values= \"", pvalues, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); PL_strcat(large_injection, JS_STOP); buf = getData( confirmDeleteConfigTemplate, large_injection ); do_free(ptype); do_free(pname); do_free(ptimestamp); do_free(pvalues); do_free(pstate); do_free(large_injection); } else if( ( PL_strstr( query, "op=delete_config_parameter" ) ) ) { tokendbDebug( "authorization for op=delete_config_parameter\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "delete_config_parameter", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "delete_config_parameter", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *ptimestamp = NULL; char *key_values = NULL; char *new_value = NULL; char *conf_list = NULL; ConfigStore *store = NULL; int return_done = 0; int status=0; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN); if ((ptype == NULL) || (pname == NULL) || (PL_strlen(pname)==0) || (PL_strlen(ptype)==0)) { error_out("Invalid Invocation: Parameter type or name is NULL or empty", "Parameter type or name is NULL or empty"); return_done = 1; goto delete_config_parameter_cleanup; } if (!config_param_exists(ptype, pname)) { error_out("Parameter does not exist", "Parameter does not exist"); return_done = 1; goto delete_config_parameter_cleanup; } status = set_config_state_timestamp(ptype, pname, ptimestamp, "Writing", "Admin", false, userid); if (status != 0) { error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date"); return_done=1; goto delete_config_parameter_cleanup; } store = get_pattern_substore(ptype, pname); key_values = (char *) store->GetOrderedList(); if (PL_strlen(key_values) > 0) parse_and_apply_changes(userid, ptype, pname, "DELETE", key_values); // remove from the list for that config type PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype ); conf_list = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); new_value = RA::remove_from_comma_list((const char*) pname, (char *)conf_list); RA::GetConfigStore()->Add(configname, new_value); // remove state and timestamp variables remove_config_state_timestamp(ptype, pname); tokendbDebug("Committing delete .."); char error_msg[512]; status = RA::GetConfigStore()->Commit(true, error_msg, 512); if (status != 0) { tokendbDebug(error_msg); } PR_snprintf(oString, 512, "%s", pname); PR_snprintf(pLongString, 4096, "%s;;%s", configname, new_value); RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, pLongString, "config item deleted"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var flash = \"Configuration changes have been saved.\";\n", "var agent_target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n", "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( indexTemplate, injection ); delete_config_parameter_cleanup: do_free(ptype); do_free(pname); do_free(key_values); do_free(new_value); do_free(ptimestamp); if (store != NULL) { delete store; store = NULL; } if (return_done == 1) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=add_config_parameter" ) ) ) { tokendbDebug( "authorization for op=add_config_parameter\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_config_parameter", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_config_parameter", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; ConfigStore *store = NULL; char *pattern = NULL; char *disp_conf_type = NULL; int return_done =0; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); if ((ptype == NULL) || (pname == NULL) || (PL_strlen(pname)==0) || (PL_strlen(ptype)==0)) { error_out("Invalid Invocation: Parameter type or name is NULL or empty", "Parameter type or name is NULL or empty"); return_done = 1; goto add_config_parameter_cleanup; } if (config_param_exists(ptype, pname)) { error_out("Parameter already exists. Use edit instead.", "Parameter already exists"); return_done = 1; goto add_config_parameter_cleanup; } /* extra check (just in case) */ store = get_pattern_substore(ptype, pname); if ((store != NULL) && (store->Size() != 0)) { error_out("Config entries already exist for this parameter. This is an error. Manually delete them first.", "Setup Error"); return_done = 1; goto add_config_parameter_cleanup; } PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype ); pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype ); disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", ptype, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_name = \"", pname, "\";\n", "var conf_pattern = \"", pattern, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed? PL_strcat(injection, JS_STOP); buf = getData( addConfigTemplate, injection ); add_config_parameter_cleanup: do_free(ptype); do_free(pname); if (store != NULL) { delete store; store = NULL; } if (return_done == 1) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=agent_change_config_state" ) ) ) { tokendbDebug( "authorization for op=agent_change_config_state\n" ); if (! is_agent) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_change_config_state", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_change_config_state", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *ptimestamp = NULL; char *choice = NULL; char pstate[128]=""; int return_done =0; int set_status = 0; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN); choice = get_post_field(post, "choice", SHORT_LEN); if ((ptype == NULL) || (pname == NULL) || (ptimestamp == NULL) || (choice == NULL)) { error_out("Invalid Invocation: A required parameter is NULL", "Invalid Invocation: A required parameter is NULL"); return_done=1; goto agent_change_config_state_cleanup; } // check if agent has permission to see this config parameter if (!agent_must_approve(ptype)) { error_out("Invalid Invocation: Agent is not permitted to change the state of this configuration item", "Invalid Invocation: Agent is not permitted to change the state of this configuration item"); return_done=1; goto agent_change_config_state_cleanup; } if ((PL_strcmp(choice, "Disable") == 0) || (PL_strcmp(choice, "Reject") == 0)) { PR_snprintf(pstate, 128, "Disabled"); } else { PR_snprintf(pstate, 128, "Enabled"); } set_status = set_config_state_timestamp(ptype, pname, ptimestamp, pstate, "Agent", false, userid); if (set_status != 0) { error_out("The data you are viewing has been changed by an administrator and is out of date. Please reload the data and try again.", "Data Out of Date"); return_done=1; goto agent_change_config_state_cleanup; } char error_msg[512]; status = RA::GetConfigStore()->Commit(false, error_msg, 512); if (status != 0) { tokendbDebug(error_msg); } PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var flash = \"Configuration changes have been saved.\";\n", "var agent_target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n", "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( indexTemplate, injection ); agent_change_config_state_cleanup: do_free(ptype); do_free(pname); do_strfree(ptimestamp); do_strfree(choice); if (return_done == 1) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=agent_view_config" ) ) ) { tokendbDebug( "authorization for op=agent_view_config\n" ); if (! is_agent) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_view_config", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_view_config", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *pstate = NULL; char *ptimestamp = NULL; char *disp_conf_type = NULL; int return_done = 0; char *key_values = NULL; char *large_injection = NULL; char *escaped = NULL; ConfigStore *store = NULL; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); if ((ptype == NULL) || (pname == NULL)) { error_out("Invalid Invocation: Parameter type or name is NULL", "Invalid Invocation: Parameter type or name is NULL"); return_done =1; goto agent_view_config_cleanup; } // check if agent has permission to see this config parameter if (! agent_must_approve(ptype)) { error_out("Invalid Invocation: Agent is not permitted to view this configuration item", "Invalid Invocation: Agent is not permitted to view this configuration item"); return_done =1; goto agent_view_config_cleanup; } get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp); store = get_pattern_substore(ptype, pname); if (store == NULL) { error_out("Setup Error: Pattern Substore is NULL", "Pattern Substore is NULL"); return_done =1; goto agent_view_config_cleanup; } key_values = (char *) store->GetOrderedList(); escaped = escapeSpecialChars(key_values); tokendbDebug( "got ordered list"); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype ); disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); large_injection = (char *) PR_Malloc(PL_strlen(key_values) + MAX_INJECTION_SIZE); PR_snprintf( large_injection, PL_strlen(key_values) + MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", ptype, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_name = \"", pname, "\";\n", "var conf_state = \"", pstate, "\";\n", "var conf_tstamp = \"", ptimestamp, "\";\n", "var conf_values= \"", escaped, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed? PL_strcat(large_injection, JS_STOP); buf = getData( agentViewConfigTemplate, large_injection ); agent_view_config_cleanup: do_free(ptype); do_free(pname); do_free(pstate); do_free(ptimestamp); do_free(key_values); do_free(large_injection); do_strfree(escaped); if (store != NULL) { delete store; store = NULL; } if (return_done != 0 ) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=edit_config_parameter" ) ) ) { tokendbDebug( "authorization for op=edit_config_parameter\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "edit_config_parameter", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "edit_config_parameter", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *pstate = NULL; char *ptimestamp = NULL; char *key_values = NULL; char *escaped = NULL; ConfigStore *store = NULL; char *large_injection = NULL; char *pattern = NULL; char *disp_conf_type = NULL; int return_done = 0; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); if ((ptype == NULL) || (pname == NULL)) { error_out("Invalid Invocation: Parameter type or name is NULL", "Invalid Invocation: Parameter type or name is NULL"); return_done =1; goto edit_config_parameter_cleanup; } get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp); tokendbDebug(pstate); tokendbDebug(ptimestamp); store = get_pattern_substore(ptype, pname); if (store == NULL) { error_out("Setup Error", "Pattern Substore is NULL"); return_done =1; goto edit_config_parameter_cleanup; } key_values = (char *) store->GetOrderedList(); //escaped = escapeSpecialChars(key_values); escaped = escapeString(key_values); tokendbDebug( "got ordered list"); PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype ); pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype ); disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); large_injection = (char *) PR_Malloc(PL_strlen(key_values) + MAX_INJECTION_SIZE); PR_snprintf( large_injection, PL_strlen(key_values) + MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", ptype, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_name = \"", pname, "\";\n", "var conf_state = \"", pstate, "\";\n", "var conf_tstamp = \"", ptimestamp, "\";\n", "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n", "var conf_pattern = \"", pattern, "\";\n", "var conf_values= \"", escaped, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed? PL_strcat(large_injection, JS_STOP); buf = getData( editConfigTemplate, large_injection ); edit_config_parameter_cleanup: do_free(ptype); do_free(pname); do_strfree(ptimestamp); do_strfree(pstate); do_free(large_injection); do_free(key_values); do_strfree(escaped); if (store != NULL) { delete store; store = NULL; } if (return_done == 1) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=return_to_edit_config_parameter" ) ) ) { tokendbDebug( "authorization for op=return_to_edit_config_parameter\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "return_to_edit_config_parameter", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "return_to_edit_config_parameter", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *pstate = NULL; char *ptimestamp = NULL; char *pvalues = NULL; char *large_injection = NULL; char *pattern = NULL; char *disp_conf_type = NULL; int return_done = 0; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); pstate = get_post_field(post, "pstate", SHORT_LEN); ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN); pvalues = get_post_field_s(post, "pvalues"); if ((ptype == NULL) || (pname == NULL) || (pstate == NULL) || (ptimestamp == NULL) || (pvalues == NULL)) { error_out("Invalid Invocation: A required parameter is missing", "Invalid Invocation: A required parameter is missing"); return_done =1; goto return_to_edit_config_parameter_cleanup; } PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype ); pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype ); disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); large_injection = (char *) PR_Malloc(PL_strlen(pvalues) + MAX_INJECTION_SIZE); PR_snprintf( large_injection, PL_strlen(pvalues) + MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", ptype, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_name = \"", pname, "\";\n", "var conf_state = \"", pstate, "\";\n", "var conf_tstamp = \"", ptimestamp, "\";\n", "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n", "var conf_pattern = \"", pattern, "\";\n", "var conf_values= \"", pvalues, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed? PL_strcat(large_injection, JS_STOP); buf = getData( editConfigTemplate, large_injection ); return_to_edit_config_parameter_cleanup: do_free(ptype); do_free(pname); do_free(ptimestamp); do_free(pstate); do_free(pvalues); do_free(large_injection); if (return_done == 1) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=confirm_config_changes" ) ) ) { tokendbDebug( "authorization for op=confirm_config_changes\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "confirm_config_changes", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "confirm_config_changes", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *pvalues = NULL; char *ptimestamp = NULL; char *choice = NULL; char *cur_ts = NULL; char *cur_state = NULL; char *changed_str = NULL; char *added_str = NULL; char *deleted_str = NULL; char *escaped_deleted_str = NULL; char *escaped_added_str = NULL; char *escaped_changed_str = NULL; char *escaped_pvalues = NULL; char *disp_conf_type = NULL; int return_done=0; char flash[512]=""; char *pair = NULL; char *line = NULL; int i; int len; char *lasts = NULL; char *value = NULL; ConfigStore *store = NULL; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN); escaped_pvalues = get_post_field_s(post, "pvalues"); choice = get_post_field(post, "choice", SHORT_LEN); if ((ptype == NULL) || (pname == NULL) || (escaped_pvalues == NULL) || (ptimestamp == NULL)) { error_out("Invalid Invocation: A required parameter is NULL", "A required parameter is NULL"); return_done=1; goto confirm_config_changes_cleanup; } tokendbDebug(ptype); tokendbDebug(pname); if (PL_strlen(escaped_pvalues) == 0) { error_out("Empty Data not allowed. Use Delete Parameter instead", "Empty Data"); return_done=1; goto confirm_config_changes_cleanup; } get_config_state_timestamp(ptype, pname, &cur_state, &cur_ts); if (PL_strcmp(cur_ts, ptimestamp) != 0) { error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date"); return_done=1; goto confirm_config_changes_cleanup; } store = get_pattern_substore(ptype, pname); if (store == NULL) { error_out("Setup Error", "Pattern Substore is NULL"); return_done=1; goto confirm_config_changes_cleanup; } // parse the pvalues string of form foo=bar&&foo2=baz&& ... pvalues = unescapeString(escaped_pvalues); changed_str = (char*) PR_Malloc(PL_strlen(pvalues)); added_str = (char*) PR_Malloc(PL_strlen(pvalues)); PR_snprintf(changed_str, PL_strlen(pvalues),""); PR_snprintf(added_str, PL_strlen(pvalues), ""); line = PL_strdup(pvalues); pair = PL_strtok_r(line, "&&", &lasts); while (pair != NULL) { len = strlen(pair); i = 0; while (1) { if (i >= len) { goto skip; } if (pair[i] == '\0') { goto skip; } if (pair[i] == '=') { pair[i] = '\0'; break; } i++; } if ((value= (char *) store->GetConfigAsString(&pair[0]))) { // key exists if (PL_strcmp(value, &pair[i+1]) != 0) { // value has changed PR_snprintf(changed_str, PL_strlen(pvalues), "%s%s%s=%s", changed_str, (PL_strlen(changed_str) != 0) ? "&&" : "", &pair[0], &pair[i+1]); } store->Remove(&pair[0]); } else { // new key PR_snprintf(added_str, PL_strlen(pvalues), "%s%s%s=%s", added_str, (PL_strlen(added_str) != 0) ? "&&" : "", &pair[0], &pair[i+1]); } skip: pair = PL_strtok_r(NULL, "&&", &lasts); } // remaining entries have been deleted deleted_str = (char *) store->GetOrderedList(); //escape special characters escaped_deleted_str = escapeString(deleted_str); escaped_added_str = escapeString(added_str); escaped_changed_str = escapeString(changed_str); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype ); disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); if ((PL_strlen(escaped_added_str) + PL_strlen(escaped_changed_str) + PL_strlen(escaped_deleted_str))!=0) { int injection_size = PL_strlen(escaped_deleted_str) + PL_strlen(escaped_pvalues) + PL_strlen(escaped_added_str) + PL_strlen(escaped_changed_str) + MAX_INJECTION_SIZE; char * large_injection = (char *) PR_Malloc(injection_size); PR_snprintf( large_injection, injection_size, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", ptype, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_name = \"", pname, "\";\n", "var conf_tstamp = \"", ptimestamp, "\";\n", "var conf_state = \"", cur_state, "\";\n", "var conf_values = \"", escaped_pvalues, "\";\n", "var added_str= \"", escaped_added_str, "\";\n", "var changed_str= \"", escaped_changed_str, "\";\n", "var conf_approval_requested = \"", (PL_strcmp(choice, "Save") == 0) ? "FALSE" : "TRUE", "\";\n", "var deleted_str= \"", escaped_deleted_str, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed? PL_strcat(large_injection, JS_STOP); buf = getData( confirmConfigChangesTemplate, large_injection ); do_free(large_injection); } else { // no changes need to be saved if (PL_strcmp(choice, "Save") != 0) { int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Pending_Approval", "Admin", false, userid); if (status != 0) { error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date"); return_done=1; goto confirm_config_changes_cleanup; } char error_msg[512]; status = RA::GetConfigStore()->Commit(false, error_msg, 512); if (status != 0) { tokendbDebug(error_msg); } PR_snprintf(flash, 512, "Configuration Parameters have been submitted for Agent Approval"); } else { PR_snprintf(flash, 512, "The data displayed is up-to-date. No changes need to be saved."); } PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var flash = \"", flash , "\";\n", "var agent_target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n", "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( indexTemplate, injection ); } confirm_config_changes_cleanup: do_strfree(cur_state); do_strfree(cur_ts); do_free(changed_str); do_free(added_str); do_free(deleted_str); do_strfree(escaped_deleted_str); do_strfree(escaped_added_str); do_strfree(escaped_changed_str); do_strfree(escaped_pvalues); do_free(ptype); do_free(pname); do_free(pvalues); do_free(ptimestamp); do_free(choice); do_strfree(line); if (store != NULL) { delete store; store = NULL; } if (return_done != 0) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=save_config_changes" ) ) ) { tokendbDebug( "authorization for op=save_config_changes\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save_config_changes", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save_config_parameter", "Success", "Tokendb user authorization"); char *ptype = NULL; char *pname = NULL; char *ptimestamp = NULL; char *escaped_added_str = NULL; char *escaped_deleted_str = NULL; char *escaped_changed_str = NULL; char *new_config = NULL; char *approval_requested = NULL; char *pstate = NULL; char flash[256] = ""; int return_done = 0; bool new_config_bool = false; ptype = get_post_field(post, "ptype", SHORT_LEN); pname = get_post_field(post, "pname", SHORT_LEN); ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN); escaped_added_str = get_post_field_s(post, "added_params"); escaped_deleted_str = get_post_field_s(post, "deleted_params"); escaped_changed_str = get_post_field_s(post, "changed_params"); new_config = get_post_field(post, "new_config", SHORT_LEN); approval_requested = get_post_field(post, "approval_requested", SHORT_LEN); new_config_bool = (PL_strcmp(new_config, "true") == 0) ? true : false; tokendbDebug(ptype); tokendbDebug(pname); tokendbDebug(new_config); tokendbDebug(ptimestamp); tokendbDebug(approval_requested); char *added_str = unescapeString(escaped_added_str); char *deleted_str = unescapeString(escaped_deleted_str); char *changed_str = unescapeString(escaped_changed_str); tokendbDebug(added_str); tokendbDebug(deleted_str); tokendbDebug(changed_str); if ((ptype == NULL) || (pname == NULL)) { error_out("Invalid Invocation: Parameter type, name or values is NULL", "Parameter type, name or values is NULL"); return_done = 1; goto save_config_changes_cleanup; } if (set_config_state_timestamp(ptype, pname, ptimestamp, "Writing", "Admin", new_config_bool, userid) != 0) { error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date"); return_done=1; goto save_config_changes_cleanup; } if (new_config) { do_free(ptimestamp); get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp); } if (PL_strlen(added_str) != 0) parse_and_apply_changes(userid, ptype, pname, "ADD", added_str); if (PL_strlen(deleted_str) != 0) parse_and_apply_changes(userid, ptype, pname, "DELETE", deleted_str); if (PL_strlen(changed_str) != 0) parse_and_apply_changes(userid, ptype, pname, "MODIFY", changed_str); if (PL_strcmp(new_config, "true") ==0) { // add to the list for that config type PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype ); const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname ); char value[4096] = ""; PR_snprintf(value, 4096, "%s%s%s", conf_list, (PL_strlen(conf_list) > 0) ? "," : "", pname); RA::GetConfigStore()->Add(configname, value); PR_snprintf(oString, 512, "%s", pname); PR_snprintf(pLongString, 4096, "%s;;%s", configname, value); RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, pLongString, "config item added"); } if (PL_strcmp(approval_requested, "TRUE") == 0) { int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Pending_Approval", "Admin", false, userid); if (status != 0) { error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date"); return_done=1; goto save_config_changes_cleanup; } PR_snprintf(flash, 256, "Configuration Parameters have been saved and submitted for approval"); } else { int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Disabled", "Admin", false, userid); if (status != 0) { error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date"); return_done=1; goto save_config_changes_cleanup; } PR_snprintf(flash, 256, "Configuration Parameters have been saved"); } if ((PL_strlen(added_str) != 0) || (PL_strlen(deleted_str) != 0) || (PL_strlen(changed_str) != 0)) { char error_msg[512]; status = RA::GetConfigStore()->Commit(true, error_msg, 512); if (status != 0) { tokendbDebug(error_msg); } RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", "", "config changes committed to filesystem"); } else { // commit state changes char error_msg[512]; status = RA::GetConfigStore()->Commit(false, error_msg, 512); if (status != 0) { tokendbDebug(error_msg); } } PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var flash = \"" , flash, "\";\n", "var agent_target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n", "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( indexTemplate, injection ); save_config_changes_cleanup: do_free(ptype); do_free(pname); do_free(added_str); do_free(deleted_str); do_free(changed_str); do_free(escaped_added_str); do_free(escaped_deleted_str); do_free(escaped_changed_str); do_free(new_config); do_free(ptimestamp); do_free(pstate); do_free(approval_requested); if (return_done == 1) { do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } } else if( ( PL_strstr( query, "op=view_admin" ) ) || ( PL_strstr( query, "op=view_certificate" ) ) || ( PL_strstr( query, "op=view_activity_admin" ) ) || ( PL_strstr( query, "op=view_activity" ) ) || ( PL_strstr( query, "op=view_users" ) ) || ( PL_strstr( query, "op=view" ) ) || ( PL_strstr( query, "op=edit_user" ) ) || ( PL_strstr( query, "op=edit" ) ) || ( PL_strstr( query, "op=show_certificate" ) ) || ( PL_strstr( query, "op=show" ) ) || ( PL_strstr( query, "op=do_confirm_token" ) ) || ( PL_strstr( query, "op=user_delete_confirm"))|| ( PL_strstr( query, "op=confirm" ) ) ) { op = get_field(query, "op=", SHORT_LEN); if( ( PL_strstr( query, "op=confirm" ) ) || ( PL_strstr( query, "op=view_admin" ) ) || ( PL_strstr( query, "op=view_activity_admin" ) ) || ( PL_strstr( query, "op=show_admin" ) ) || ( PL_strstr( query, "op=view_users") ) || ( PL_strstr( query, "op=edit_user") ) || ( PL_strstr( query, "op=user_delete_confirm") ) ) { tokendbDebug( "authorization for admin ops\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization"); } else if ((PL_strstr(query, "op=edit")) || (PL_strstr(query, "do_confirm_token"))) { tokendbDebug( "authorization for op=edit and op=do_confirm_token\n" ); if (! is_agent ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization"); } else if (PL_strstr(query, "op=view_activity")) { tokendbDebug( "authorization for view_activity\n" ); /* check removed -- all roles permitted if ( (! is_agent) && (! is_operator) && (! is_admin)) { error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DECLINED; } */ } else { tokendbDebug( "authorization\n" ); if ((! is_agent) && (!is_operator)) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization"); } do_free(op); if ((PL_strstr( query, "op=view_activity_admin")) || (PL_strstr( query, "op=view_activity" ) )) { getActivityFilter( filter, query ); } else if( PL_strstr( query, "op=view_certificate" ) ) { getCertificateFilter( filter, query ); } else if( PL_strstr( query, "op=show_certificate" ) ) { getCertificateFilter( filter, query ); } else if ((PL_strstr( query, "op=view_users" ) ) || (PL_strstr( query, "op=user_delete_confirm")) || (PL_strstr( query, "op=edit_user" ) )) { getUserFilter( filter, query ); } else { getFilter( filter, query ); } auth_filter = get_authorized_profiles(userid, is_admin); tokendbDebug("auth_filter"); tokendbDebug(auth_filter); char *complete_filter = add_profile_filter(filter, auth_filter); do_free(auth_filter); int time_limit = get_time_limit(query); int size_limit = get_size_limit(query); tokendbDebug( "looking for filter:" ); tokendbDebug( complete_filter ); tokendbDebug( filter ); tokendbDebug( "\n" ); /* retrieve maxCount */ s1 = PL_strstr( query, "maxCount=" ); if( s1 == NULL ) { maxReturns = 100; } else { s2 = PL_strchr( ( const char * ) s1, '&' ); if( s2 == NULL ) { maxReturns = atoi( s1+9 ); } else { *s2 = '\0'; maxReturns = atoi( s1+9 ); *s2 = '&'; } } if (( PL_strstr( query, "op=view_activity_admin_all" )) || ( PL_strstr( query, "op=view_activity_all") )) { // TODO: error check to confirm that search filter is non-empty status = find_tus_activity_entries_no_vlv( complete_filter, &result, 1 ); } else if (( PL_strstr( query, "op=view_activity_admin" )) || ( PL_strstr( query, "op=view_activity" ) )) { if (PL_strcmp(complete_filter, "(&(tokenID=*)(tokenUserID=*))") == 0) { tokendbDebug("activity vlv search"); status = find_tus_activity_entries(complete_filter, maxReturns, &result); } else { status = find_tus_activity_entries_pcontrol_1( complete_filter, maxReturns, time_limit, size_limit, &result); } } else if(( PL_strstr( query, "op=view_certificate_all" ) ) || ( PL_strstr( query, "op=show_certificate") )) { // TODO: error check to confirm that search filter is non-empty ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "LDAP filter: %s", complete_filter); status = find_tus_certificate_entries_by_order_no_vlv( complete_filter, &result, 0 ); } else if( PL_strstr( query, "op=view_certificate" )) { ap_log_error( ( const char * ) "tus", __LINE__, APLOG_MODULE_INDEX, APLOG_ERR, 0, rq->server, ( const char * ) "LDAP filter: %s", complete_filter); status = find_tus_certificate_entries_by_order( complete_filter, maxReturns, &result, 0 ); } else if( PL_strstr( query, "op=show_admin" ) || PL_strstr( query, "op=show" ) || PL_strstr( query, "op=confirm" ) || PL_strstr( query, "op=do_confirm_token" ) ) { status = find_tus_token_entries_no_vlv( complete_filter, &result, 0 ); } else if ((PL_strstr (query, "op=view_users" )) || (PL_strstr (query, "op=user_delete_confirm")) || (PL_strstr (query, "op=edit_user" ))) { status = find_tus_user_entries_no_vlv( filter, &result, 0); } else { if (PL_strcmp(complete_filter, "(&(cn=*)(tokenUserID=*))") == 0) { tokendbDebug("token vlv search"); status = find_tus_db_entries(complete_filter, maxReturns, &result); } else { status = find_tus_db_entries_pcontrol_1( complete_filter, maxReturns, time_limit, size_limit, &result ); } } if( status != LDAP_SUCCESS ) { ldap_error_out("LDAP search error: ", "LDAP search error: %s"); do_free(complete_filter); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } do_free(complete_filter); nEntries = get_number_of_entries( result ); entryNum = 0; size = 0; PL_strcpy( injection, JS_START ); PL_strcat( injection, "var userid = \"" ); PL_strcat( injection, userid ); PL_strcat( injection, "\";\n" ); PL_strcat( injection, "var uriBase = \"" ); PL_strcat( injection, uri ); PL_strcat( injection, "\";\n" ); if( nEntries > 1 ) { if( sendInPieces && PL_strstr( query, "op=view_activity_admin" ) ) { buf = getTemplateFile( searchActivityAdminResultTemplate, &tagOffset ); if( buf != NULL && tagOffset >= 0 ) { ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq ); sendPieces = 1; } } else if( sendInPieces && PL_strstr( query, "op=view_activity" ) ) { buf = getTemplateFile( searchActivityResultTemplate, &tagOffset ); if( buf != NULL && tagOffset >= 0 ) { ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq ); sendPieces = 1; } } else if( sendInPieces && PL_strstr( query, "op=view_certificate" ) ) { buf = getTemplateFile( searchCertificateResultTemplate, &tagOffset ); if( buf != NULL && tagOffset >= 0 ) { ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq ); sendPieces = 1; } } else if (sendInPieces && PL_strstr( query, "op=view_users" )) { buf = getTemplateFile( searchUserResultTemplate, &tagOffset ); if( buf != NULL && tagOffset >= 0 ) { ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq ); sendPieces = 1; } } else if( sendInPieces && PL_strstr( query, "op=view" ) ) { buf = getTemplateFile( searchResultTemplate, &tagOffset ); if( buf != NULL && tagOffset >= 0 ) { ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq ); sendPieces = 1; } } PL_strcat( injection, "var total = \"" ); len = PL_strlen( injection ); PR_snprintf( &injection[len], ( MAX_INJECTION_SIZE-len ), "%d", nEntries ); PL_strcat( injection, "\";\n" ); } else { if( ( vals = get_token_states() ) != NULL ) { PL_strcat( injection, "var tokenStates = \"" ); for( i = 0; vals[i] != NULL; i++ ) { if( i > 0 ) { PL_strcat( injection, "," ); } PL_strcat( injection, vals[i] ); } if( i > 0 ) { PL_strcat( injection, "\";\n" ); } else { PL_strcat( injection, "null;\n" ); } } } PL_strcat( injection, "var results = new Array();\n" ); PL_strcat( injection, "var item = 0;\n" ); if( PL_strstr( query, "op=do_confirm_token" ) ) { question = PL_strstr( query, "question=" ); q = question[9] - '0'; PR_snprintf( question_no, 256, "%d", q ); PL_strcat( injection, "var question = \"" ); PL_strcat( injection, question_no ); PL_strcat( injection, "\";\n" ); } if (PL_strstr( query, "op=do_confirm_token" ) || PL_strstr( query, "op=show" )) { show_token_ui_state = true; } /* get attributes to be displayed to the user */ if (( PL_strstr( query, "op=view_activity_admin" ) ) || ( PL_strstr( query, "op=view_activity" ) )) { attrs = get_activity_attributes(); } else if( PL_strstr( query, "op=view_certificate" ) ) { attrs = get_certificate_attributes(); } else if( PL_strstr( query, "op=show_certificate" ) ) { attrs = get_certificate_attributes(); } else if ((PL_strstr( query, "op=user_delete_confirm")) || (PL_strstr( query, "op=edit_user") ) ) { attrs = get_user_attributes(); } else if (PL_strstr( query, "op=view_users") ) { attrs = get_view_user_attributes(); } else { attrs = get_token_attributes(); } /* start_val used in paging of profiles on the edit_user page */ if (PL_strstr( query, "op=edit_user") ) { char *start_val_str = get_field(query, "start_val=", SHORT_LEN); if (start_val_str != NULL) { start_val = atoi(start_val_str); do_free(start_val_str); } else { start_val = 0; } end_val = start_val + NUM_PROFILES_TO_DISPLAY; } /* flash used to display edit result upon redirection back to the edit_user page */ if (PL_strstr(query, "op=edit_user") ) { char *flash = get_field(query, "flash=", SHORT_LEN); if (flash != NULL) { PL_strcat(injection, "var flash = \""); PL_strcat(injection, flash); PL_strcat(injection, "\";\n"); do_free(flash); } PR_snprintf(msg, 256, "var num_profiles_to_display = %d ;\n", NUM_PROFILES_TO_DISPLAY); PL_strcat(injection, msg); } int injection_size = MAX_INJECTION_SIZE; /* start_entry_val is used for pagination of entries on all other pages */ int start_entry_val; int end_entry_val; int first_pass = 1; int one_time = 1; char *start_entry_val_str = get_field(query, "start_entry_val=", SHORT_LEN); if (start_entry_val_str != NULL) { start_entry_val = atoi(start_entry_val_str); do_free(start_entry_val_str); } else { start_entry_val = 1; } end_entry_val = start_entry_val + NUM_ENTRIES_PER_PAGE; if( (maxReturns > 0) && (maxReturns < nEntries)) { PR_snprintf(msg, 256, "var limited = %d ;\n", maxReturns); PL_strcat( injection, msg); } for( e = get_first_entry( result ); ( maxReturns > 0 ) && ( e != NULL ); e = get_next_entry( e ) ) { maxReturns--; entryNum++; if ((entryNum < start_entry_val) || (entryNum >= end_entry_val)) { if (one_time == 1) { PL_strcat(injection, "var my_query = \""); PL_strcat(injection, query); PL_strcat(injection, "\";\n"); one_time =0; } // skip values not within the page range if (entryNum == end_entry_val) { PL_strcat( injection, "var has_more_entries = 1;\n"); break; } continue; } PL_strcat( injection, "var o = new Object();\n" ); for( n = 0; attrs[n] != NULL; n++ ) { /* Get the values of the attribute. */ if( ( bvals = get_attribute_values( e, attrs[n] ) ) != NULL ) { int v_start =0; int v_end = MAX_INJECTION_SIZE; PL_strcat( injection, "o." ); PL_strcat( injection, attrs[n] ); PL_strcat( injection, " = " ); if (PL_strstr(attrs[n], PROFILE_ID)) { v_start = start_val; v_end = end_val; } for( i = v_start; (bvals[i] != NULL) && (i < v_end); i++ ) { if( i > start_val ) { PL_strcat( injection, "#" ); } else { PL_strcat( injection, "\"" ); } // make sure to escape any special characters if (bvals[i]->bv_val != NULL) { char *escaped = escapeSpecialChars(bvals[i]->bv_val); PL_strcat( injection, escaped ); if (escaped != NULL) { PL_strfree(escaped); } } } if( i > v_start ) { PL_strcat( injection, "\";\n" ); } else { PL_strcat( injection, "null;\n" ); } if ((PL_strcmp(attrs[n], TOKEN_STATUS)==0) && show_token_ui_state && valid_berval(bvals)) { PL_strncpy( tokenStatus, bvals[0]->bv_val, 100 ); } if ((PL_strcmp(attrs[n], TOKEN_REASON)==0) && show_token_ui_state && valid_berval(bvals)) { PL_strncpy( tokenReason, bvals[0]->bv_val, 100 ); } if (PL_strstr(attrs[n], PROFILE_ID)) { if (bvals[i] != NULL) { PL_strcat( injection, "var has_more_profile_vals = \"true\";\n"); } else { PL_strcat( injection, "var has_more_profile_vals = \"false\";\n"); } PR_snprintf(msg, 256, "var start_val = %d ;\n var end_val = %d ;\n", start_val, i); PL_strcat( injection, msg); } /* Free the attribute values from memory when done. */ if( bvals != NULL ) { free_values( bvals, 1 ); bvals = NULL; } } } PL_strcat( injection, "results[item++] = o;\n" ); if (check_injection_size(&injection, &injection_size, fixed_injection) != 0) { // failed to allocate more space to injection, truncating output break; } if( first_pass == 1 && nEntries > 1 && sendPieces == 0 ) { first_pass=0; PR_snprintf(msg, 256, "var start_entry_val = %d ; \nvar num_entries_per_page= %d ; \n", start_entry_val, NUM_ENTRIES_PER_PAGE); PL_strcat( injection, msg); } if( sendPieces ) { ( void ) ap_rwrite( ( const void * ) injection, PL_strlen( injection ), rq ); injection[0] = '\0'; } } if( result != NULL ) { free_results( result ); result = NULL; } /* populate the user roles */ if ((PL_strstr( query, "op=edit_user")) || (PL_strstr( query, "op=user_delete_confirm"))) { uid = get_field(query, "uid=", SHORT_LEN); bool officer = false; bool agent = false; bool admin = false; status = find_tus_user_role_entries( uid, &result ); for (e = get_first_entry( result ); e != NULL; e = get_next_entry( e ) ) { char *dn = NULL; dn = get_dn(e); if (PL_strstr(dn, "Operators")) officer=true; if (PL_strstr(dn, "Agents")) agent = true; if (PL_strstr(dn, "Administrators")) admin = true; if (dn != NULL) { PL_strfree(dn); dn=NULL; } } if (officer) { PL_strcat( injection, "var operator = \"CHECKED\"\n"); } else { PL_strcat( injection, "var operator = \"\"\n"); } if (agent) { PL_strcat( injection, "var agent = \"CHECKED\"\n"); } else { PL_strcat( injection, "var agent = \"\"\n"); } if (admin) { PL_strcat( injection, "var admin = \"CHECKED\"\n"); } else { PL_strcat( injection, "var admin = \"\"\n"); } if( result != NULL ) { free_results( result ); result = NULL; } do_free(uid); } /* populate the profile checkbox */ /* for sanity, we limit the number of entries displayed as well as the max number of characters transferred */ if (PL_strstr( query, "op=edit_user")) { if (profileList != NULL) { int n_profiles = 0; int l_profiles = 0; bool more_profiles = false; char *pList = PL_strdup(profileList); char *sresult = NULL; PL_strcat( injection, "var profile_list = new Array("); sresult = strtok(pList, ","); n_profiles++; while (sresult != NULL) { n_profiles++; l_profiles += PL_strlen(sresult); if ((n_profiles > NUM_PROFILES_TO_DISPLAY) || (l_profiles > MAX_LEN_PROFILES_TO_DISPLAY)) { PL_strcat(injection, "\"Other Profiles\","); more_profiles = true; break; } PL_strcat(injection, "\""); PL_strcat(injection, sresult); PL_strcat(injection, "\","); sresult = strtok(NULL, ","); } do_free(pList); PL_strcat(injection, "\"All Profiles\")\n"); if (more_profiles) { PL_strcat(injection, "var more_profiles=\"true\";\n"); } else { PL_strcat(injection, "var more_profiles=\"false\";\n"); } } } topLevel = get_field(query, "top=", SHORT_LEN); if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) { PL_strcat(injection, "var topLevel = \"operator\";\n"); } do_free(topLevel); /* populate the authorized token transitions */ if (show_token_ui_state) { token_ui_state = get_token_ui_state(tokenStatus, tokenReason); add_allowed_token_transitions(token_ui_state, injection); } add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat( injection, JS_STOP ); if( sendPieces ) { ( void ) ap_rwrite( ( const void * ) injection, PL_strlen( injection ), rq ); mNum = buf + tagOffset + PL_strlen( CMS_TEMPLATE_TAG ); ( void ) ap_rwrite( ( const void * ) mNum, PL_strlen( mNum ), rq ); mNum = NULL; if( buf != NULL ) { PR_Free( buf ); buf = NULL; } } else { if( PL_strstr( query, "op=view_activity_admin" ) ) { buf = getData( searchActivityAdminResultTemplate, injection ); } else if( PL_strstr( query, "op=view_activity" ) ) { buf = getData( searchActivityResultTemplate, injection ); } else if( PL_strstr( query, "op=view_certificate" ) ) { buf = getData( searchCertificateResultTemplate, injection ); } else if( PL_strstr( query, "op=show_admin" ) ) { buf = getData( showAdminTemplate, injection ); } else if( PL_strstr( query, "op=view_admin" ) ) { buf = getData( searchAdminResultTemplate, injection ); } else if (PL_strstr( query, "op=view_users") ) { buf = getData( searchUserResultTemplate, injection); } else if( PL_strstr( query, "op=view" ) ) { buf = getData( searchResultTemplate, injection ); } else if (PL_strstr( query, "op=edit_user") ) { buf = getData( editUserTemplate, injection); } else if( PL_strstr( query, "op=edit" ) ) { buf = getData( editTemplate, injection ); } else if( PL_strstr( query, "op=show_certificate" ) ) { buf = getData( showCertTemplate, injection ); } else if( PL_strstr( query, "op=do_confirm_token" ) ) { buf = getData( doTokenConfirmTemplate, injection ); } else if( PL_strstr( query, "op=show" ) ) { buf = getData( showTemplate, injection ); } else if( PL_strstr( query, "op=confirm" ) ) { buf = getData( deleteTemplate, injection ); } else if ( PL_strstr( query, "op=user_delete_confirm" ) ) { buf = getData( userDeleteTemplate, injection ); } } if( injection != fixed_injection ) { if( injection != NULL ) { PR_Free( injection ); injection = NULL; } injection = fixed_injection; } } else if ( PL_strstr( query, "op=add_profile_user" )) { tokendbDebug("authorization for op=add_profile_user"); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_profile_user", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_profile_user", "Success", "Tokendb user authorization"); uid = get_post_field(post, "uid", SHORT_LEN); char *profile = get_post_field(post, "profile_0", SHORT_LEN); char *other_profile = get_post_field(post, "other_profile", SHORT_LEN); if ((profile != NULL) && (uid != NULL)) { if (PL_strstr(profile, "Other Profiles")) { if ((other_profile != NULL) && (match_profile(other_profile))) { do_free(profile); profile = PL_strdup(other_profile); } else { error_out("Invalid Profile to be added", "Invalid Profile to be added"); do_free(profile); do_free(other_profile); do_free(uid); do_free(buf); do_strfree(uri); do_strfree(query); return OK; } } if (PL_strstr(profile, ALL_PROFILES)) { status = delete_all_profiles_from_user(userid, uid); } PR_snprintf(oString, 512, "userid;;%s", uid); PR_snprintf(pString, 512, "profile;;%s", profile); status = add_profile_to_user(userid, uid, profile); if ((status != LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, pString, "failure adding profile to user"); PR_snprintf(msg, 512, "LDAP Error in adding profile %s to user %s", profile, uid); post_ldap_error(msg); } RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "profile added to user"); } do_free(other_profile); do_free(buf); do_strfree(uri); do_strfree(query); PR_snprintf((char *)msg, 512, "'%s' has added profile %s to user %s", userid, profile, uid); RA::tdb_activity(rq->connection->client_ip, "", "add_profile", "success", msg, uid, NO_TOKEN_TYPE); PR_snprintf(oString, 512, "userid;;%s", uid); PR_snprintf(pString, 512, "profile;;%s", profile); PR_snprintf(injection, MAX_INJECTION_SIZE, "/tus/tus?op=edit_user&uid=%s&flash=Profile+%s+has+been+added+to+the+user+record", uid, profile); do_free(profile); do_free(uid); rq->method = apr_pstrdup(rq->pool, "GET"); rq->method_number = M_GET; ap_internal_redirect_handler(injection, rq); return OK; } else if ( PL_strstr( query, "op=save_user" )) { tokendbDebug( "authorization for op=save_user\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save_user", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save_user", "Success", "Tokendb user authorization"); // first save user details uid = get_post_field(post, "uid", SHORT_LEN); firstName = get_post_field(post, "firstName", SHORT_LEN); lastName = get_post_field(post, "lastName", SHORT_LEN); userCert = get_encoded_post_field(post, "userCert", HUGE_STRING_LEN); opOperator = get_post_field(post, "opOperator", SHORT_LEN); opAgent = get_post_field(post, "opAgent", SHORT_LEN); opAdmin = get_post_field(post, "opAdmin", SHORT_LEN); // construct audit log message PR_snprintf(oString, 512, "userid;;%s", uid); PR_snprintf(pLongString, 4096, ""); PR_snprintf(filter, 512, "uid=%s", uid); status = find_tus_user_entries_no_vlv( filter, &result, 0); e = get_first_entry( result ); if( e != NULL ) { audit_attribute_change(e, "givenName", firstName, pLongString); audit_attribute_change(e, "sn", lastName, pLongString); } if( result != NULL ) { free_results( result ); result = NULL; } // now check cert char *test_user = tus_authenticate(userCert); if ((test_user != NULL) && (strcmp(test_user, uid) == 0)) { // cert did not change } else { if (strlen(pLongString) > 0) PL_strcat(pLongString, "+"); PR_snprintf(pLongString, 4096, "%suserCertificate;;%s", pLongString, userCert); } PR_snprintf((char *)userCN, 256, "%s%s%s", ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""), ((firstName != NULL && PL_strlen(firstName) > 0)? " ": ""), lastName); status = update_user_db_entry(userid, uid, lastName, firstName, userCN, userCert); do_free(firstName); do_free(lastName); do_free(userCert); if( status != LDAP_SUCCESS ) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pLongString, "user record failed to be updated"); ldap_error_out("LDAP modify error: ", "LDAP error: %s"); do_free(buf); do_strfree(uri); do_strfree(query); do_free(uid); do_free(opOperator); do_free(opAgent); do_free(opAdmin); return DONE; } if (strlen(pLongString) > 0) RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pLongString, "user record updated"); bool has_role = tus_authorize(TOKENDB_OPERATORS_IDENTIFIER, uid); PR_snprintf(pString, 512, "role;;operator"); if ((opOperator != NULL) && (PL_strstr(opOperator, OPERATOR))) { if (!has_role) { status = add_user_to_role_db_entry(userid, uid, OPERATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role"); PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, OPERATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role"); } } } else if (has_role) { status = delete_user_from_role_db_entry(userid, uid, OPERATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role"); PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role"); } } has_role = tus_authorize(TOKENDB_AGENTS_IDENTIFIER, uid); PR_snprintf(pString, 512, "role;;agent"); if ((opAgent != NULL) && (PL_strstr(opAgent, AGENT))) { if (!has_role) { status = add_user_to_role_db_entry(userid, uid, AGENT); if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role"); PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, AGENT); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role"); } } } else if (has_role) { status = delete_user_from_role_db_entry(userid, uid, AGENT); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role"); PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role"); } } has_role = tus_authorize(TOKENDB_ADMINISTRATORS_IDENTIFIER, uid); PR_snprintf(pString, 512, "role;;administrator"); if ((opAdmin != NULL) && (PL_strstr(opAdmin, ADMINISTRATOR))) { if (!has_role) { status = add_user_to_role_db_entry(userid, uid, ADMINISTRATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role"); PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, ADMINISTRATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role"); } } } else if (has_role) { status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role"); PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role"); } } do_free(opOperator); do_free(opAgent); do_free(opAdmin); // save profile details char *nProfileStr = get_post_field(post, "nProfiles", SHORT_LEN); int nProfiles = atoi (nProfileStr); do_free(nProfileStr); for (int i=0; i< nProfiles; i++) { char p_name[256]; char p_delete[256]; PR_snprintf(p_name, 256, "profile_%d", i); PR_snprintf(p_delete, 256, "delete_%d", i); char *profile = get_post_field(post, p_name, SHORT_LEN); char *p_del = get_post_field(post, p_delete, SHORT_LEN); if ((profile != NULL) && (p_del != NULL) && (PL_strstr(p_del, "delete"))) { PR_snprintf(pString, 512, "profile_id;;%s", profile); status = delete_profile_from_user(userid, uid, profile); if ((status != LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "error deleting profile from user"); PR_snprintf(msg, 512, "LDAP Error in deleting profile %s from user %s", profile, uid); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "profile deleted from user"); } } do_free(profile); do_free(p_del); } do_free(buf); do_strfree(uri); do_strfree(query); PR_snprintf((char *)msg, 512, "'%s' has modified user %s", userid, uid); RA::tdb_activity(rq->connection->client_ip, "", "modify_user", "success", msg, uid, NO_TOKEN_TYPE); PR_snprintf(injection, MAX_INJECTION_SIZE, "/tus/tus?op=edit_user&uid=%s&flash=User+record+%s+has+been+updated", uid, uid); do_free(uid); rq->method = apr_pstrdup(rq->pool, "GET"); rq->method_number = M_GET; ap_internal_redirect_handler(injection, rq); return OK; } else if( PL_strstr( query, "op=save" ) ) { tokendbDebug( "authorization\n" ); if( ! is_agent ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save", "Success", "Tokendb user authorization"); getCN( filter, query ); mNum = parse_modification_number( query ); mods = getModifications( query ); if( mNum != NULL ) { status = check_and_modify_tus_db_entry( userid, filter, mNum, mods ); PL_strfree( mNum ); mNum = NULL; } else { status = modify_tus_db_entry( userid, filter, mods ); } int cc; PR_snprintf(oString, 512, "token_id;;%s", filter); PR_snprintf(pLongString, 4096, ""); int first_item = 1; for (cc = 0; mods[cc] != NULL; cc++) { if (! first_item) PL_strcat(pLongString, "+"); if (mods[cc]->mod_type != NULL) { PL_strcat(pLongString, mods[cc]->mod_type); PL_strcat(pLongString, ";;"); PL_strcat(pLongString, *mods[cc]->mod_values); first_item =0; } } if( mods != NULL ) { free_modifications( mods, 0 ); mods = NULL; } if( status != LDAP_SUCCESS ) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pLongString, "failed to modify token record"); ldap_error_out("LDAP modify error: ", "LDAP error: %s"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pLongString, "token record modified"); PR_snprintf((char *)msg, 256, "Token record modified by %s", userid); RA::tdb_activity(rq->connection->client_ip, cuid, "save", "success", msg, cuidUserId, tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var tid = \"", filter, "\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( editResultTemplate, injection ); } else if ( PL_strstr( query, "op=do_delete_user" ) ) { tokendbDebug( "authorization for do_delete_user\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "do_delete_user", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "do_delete_user", "Success", "Tokendb user authorization"); uid = get_post_field(post, "uid", SHORT_LEN); if (uid == NULL) { error_out("Error in delete user. userid is null", "Error in delete user. userid is null"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } bool officer = false; bool agent = false; bool admin = false; status = find_tus_user_role_entries( uid, &result ); for (e = get_first_entry( result ); e != NULL; e = get_next_entry( e ) ) { char *dn = NULL; dn = get_dn(e); if (PL_strstr(dn, "Operators")) officer=true; if (PL_strstr(dn, "Agents")) agent = true; if (PL_strstr(dn, "Administrators")) admin = true; if (dn != NULL) { PL_strfree(dn); dn=NULL; } } if (result != NULL) { free_results( result ); result = NULL; } if (officer) { status = delete_user_from_role_db_entry(userid, uid, OPERATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR); post_ldap_error(msg); } } if (agent) { status = delete_user_from_role_db_entry(userid, uid, AGENT); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT); post_ldap_error(msg); } } if (admin) { status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR); post_ldap_error(msg); } } status = delete_user_db_entry(userid, uid); if ((status != LDAP_SUCCESS) && (status != LDAP_NO_SUCH_OBJECT)) { PR_snprintf(oString, 512, "uid;;%s", uid); PR_snprintf(pString, 512, "status;;%d", status); RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "error in deleting user"); PR_snprintf(msg, 512, "Error deleting user %s", uid); ldap_error_out(msg, msg); do_free(buf); do_strfree(uri); do_strfree(query); do_free(uid); return DONE; } PR_snprintf((char *)msg, 256, "'%s' has deleted user %s", userid, uid); RA::tdb_activity(rq->connection->client_ip, "", "delete_user", "success", msg, uid, NO_TOKEN_TYPE); PR_snprintf(oString, 512, "uid;;%s", uid); RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, "", "tokendb user deleted"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var tid = \"", uid, "\";\n", "var deleteType = \"user\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); do_free(uid); buf = getData( deleteResultTemplate, injection ); } else if ( PL_strstr( query, "op=addUser" ) ) { tokendbDebug( "authorization for addUser\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "addUser", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "addUser", "Success", "Tokendb user authorization"); uid = get_post_field(post, "userid", SHORT_LEN); firstName = get_post_field(post, "firstName", SHORT_LEN); lastName = get_post_field(post, "lastName", SHORT_LEN); opOperator = get_post_field(post, "opOperator", SHORT_LEN); opAdmin = get_post_field(post, "opAdmin", SHORT_LEN); opAgent = get_post_field(post, "opAgent", SHORT_LEN); userCert = get_encoded_post_field(post, "cert", HUGE_STRING_LEN); if ((PL_strlen(uid) == 0) || (PL_strlen(lastName) == 0)) { error_out("Bad input to op=addUser", "Bad input to op=addUser"); do_free(uid); do_free(firstName); do_free(lastName); do_free(opOperator); do_free(opAdmin); do_free(opAgent); do_free(userCert); do_free(buf); do_strfree(uri); do_strfree(query); return OK; } PR_snprintf((char *)userCN, 256, "%s%s%s", ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""), ((firstName != NULL && PL_strlen(firstName) > 0)? " ": ""), lastName); PR_snprintf(oString, 512, "uid;;%s", uid); PR_snprintf(pString, 512, "givenName;;%s+sn;;%s", ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""), lastName); /* to meet STIG requirements, every user in ldap must have a password, even if that password is never used */ char *pwd = generatePassword(pwLength); status = add_user_db_entry(userid, uid, pwd, lastName, firstName, userCN, userCert); do_free(pwd); if (status != LDAP_SUCCESS) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, pString, "failure in adding tokendb user"); PR_snprintf((char *)msg, 512, "LDAP Error in adding new user %s", uid); ldap_error_out(msg, msg); do_free(uid); do_free(firstName); do_free(lastName); do_free(opOperator); do_free(opAdmin); do_free(opAgent); do_free(userCert); do_free(buf); do_strfree(uri); do_strfree(query); return OK; } PR_snprintf((char *)msg, 512, "'%s' has created new user %s", userid, uid); RA::tdb_activity(rq->connection->client_ip, "", "add_user", "success", msg, uid, NO_TOKEN_TYPE); RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "tokendb user added"); PR_snprintf(pString, 512, "role;;operator"); if ((opOperator != NULL) && (PL_strstr(opOperator, OPERATOR))) { status = add_user_to_role_db_entry(userid, uid, OPERATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role"); PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, OPERATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role"); } } else { status = delete_user_from_role_db_entry(userid, uid, OPERATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role"); PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role"); } } PR_snprintf(pString, 512, "role;;agent"); if ((opAgent != NULL) && (PL_strstr(opAgent, AGENT))) { status = add_user_to_role_db_entry(userid, uid, AGENT); if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role"); PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, AGENT); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role"); } } else { status = delete_user_from_role_db_entry(userid, uid, AGENT); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role"); PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role"); } } PR_snprintf(pString, 512, "role;;admin"); if ((opAdmin != NULL) && (PL_strstr(opAdmin, ADMINISTRATOR))) { status = add_user_to_role_db_entry(userid, uid, ADMINISTRATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role"); PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, ADMINISTRATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role"); } } else { status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR); if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role"); PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR); post_ldap_error(msg); } else { RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role"); } } do_free(firstName); do_free(lastName); do_free(opOperator); do_free(opAdmin); do_free(opAgent); do_free(userCert); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var tid = \"", uid, "\";\n", "var addType = \"user\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); do_free(uid); buf = getData( addResultTemplate, injection ); } else if( PL_strstr( query, "op=add" ) ) { tokendbDebug( "authorization for op=add\n" ); RA_Status token_type_status; if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add", "Success", "Tokendb user authorization"); getCN( filter, query ); if (m_processor.GetTokenType(OP_PREFIX, 0, 0, filter, (const char*) NULL, (NameValueSet*) NULL, token_type_status, tokentype)) { PL_strcpy(tokenType, tokentype); } else { PL_strcpy(tokenType, NO_TOKEN_TYPE); } if( strcmp( filter, "" ) == 0 ) { error_out("No Token ID Found", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } status = add_default_tus_db_entry( NULL, userid, filter, "uninitialized", NULL, NULL, tokenType ); PR_snprintf(oString, 512, "token_id;;%s", filter); if( status != LDAP_SUCCESS ) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, "", "failed to add token record"); ldap_error_out("LDAP add error: ", "LDAP error: %s"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, "", "token record added"); PR_snprintf((char *)msg, 256, "'%s' has created new token", userid); RA::tdb_activity(rq->connection->client_ip, filter, "add", "token", msg, "success", tokenType); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var tid = \"", filter, "\";\n", "var addType = \"token\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( addResultTemplate, injection ); } else if( PL_strstr( query, "op=delete" ) ) { RA_Status token_type_status; tokendbDebug( "authorization for op=delete\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "delete", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "delete", "Success", "Tokendb user authorization"); getCN( filter, query ); if (m_processor.GetTokenType(OP_PREFIX, 0, 0, filter, (const char*) NULL, (NameValueSet*) NULL, token_type_status, tokentype)) { PL_strcpy(tokenType, tokentype); } else { PL_strcpy(tokenType, NO_TOKEN_TYPE); } PR_snprintf((char *)msg, 256, "'%s' has deleted token", userid); RA::tdb_activity(rq->connection->client_ip, filter, "delete", "token", msg, "", tokenType); PR_snprintf(oString, 512, "token_id;;%s", filter); status = delete_tus_db_entry( userid, filter ); if( status != LDAP_SUCCESS ) { RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, "", "failure in deleting token record"); ldap_error_out("LDAP delete error: ", "LDAP error: %s"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, "", "token record deleted"); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var tid = \"", filter, "\";\n", "var deleteType = \"token\";\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( deleteResultTemplate, injection ); } else if ( PL_strstr( query, "op=audit_admin") ) { tokendbDebug( "authorization for op=audit_admin\n" ); if (!is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "audit_admin", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "audit_admin", "Success", "Tokendb user authorization"); PR_snprintf (injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%d%s%s%d%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var signedAuditEnable = \"", RA::m_audit_enabled ? "true": "false", "\";\n", "var logSigningEnable = \"", RA::m_audit_signed ? "true" : "false", "\";\n", "var signedAuditLogInterval = \"", RA::m_flush_interval, "\";\n", "var signedAuditLogBufferSize = \"", RA::m_buffer_size, "\";\n", "var signedAuditSelectedEvents = \"", RA::m_signedAuditSelectedEvents, "\";\n", "var signedAuditSelectableEvents = \"", RA::m_signedAuditSelectableEvents, "\";\n", "var signedAuditNonSelectableEvents = \"", RA::m_signedAuditNonSelectableEvents, "\";\n"); RA::Debug( "mod_tokendb::mod_tokendb_handler", "signedAudit: %s %s %d %d %s %s %s", RA::m_audit_enabled ? "true": "false", RA::m_audit_signed ? "true": "false", RA::m_flush_interval, RA::m_buffer_size, RA::m_signedAuditSelectedEvents, RA::m_signedAuditSelectableEvents, RA::m_signedAuditNonSelectableEvents); char *flash = get_field(query, "flash=", SHORT_LEN); if (flash != NULL) { PL_strcat(injection, "var flash = \""); PL_strcat(injection, flash); PL_strcat(injection, "\";\n"); do_free(flash); } add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData(auditAdminTemplate, injection); } else if (PL_strstr( query, "op=update_audit_admin") ) { tokendbDebug( "authorization for op=audit_admin\n" ); if (!is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "update_audit_admin", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "update_audit_admin", "Success", "Tokendb user authorization"); int need_update=0; bool o_signing = RA::m_audit_signed; bool n_signing = o_signing; char *logSigning = get_post_field(post, "logSigningEnable", SHORT_LEN); if (logSigning != NULL) { n_signing = (PL_strcmp(logSigning, "true") == 0)? true: false; } do_free(logSigning); bool o_enable = RA::m_audit_enabled; bool n_enable = o_enable; char *auditEnable = get_post_field(post, "auditEnable", SHORT_LEN); if (auditEnable != NULL) { n_enable = (PL_strcmp(auditEnable, "true") == 0)? true: false; } do_free(auditEnable); if ((o_signing == n_signing) && (o_enable == n_enable)) { // nothing changed, continue } else { if (o_signing != n_signing) { PR_snprintf(pString, 512, "logging.audit.logSigning;;%s", (n_signing)? "true":"false"); if (o_enable != n_enable) { PL_strcat(pString, "+logging.audit.enable;;"); PL_strcat(pString, (n_enable)? "true" : "false"); } } else { PR_snprintf(pString, 512, "logging.audit.enable;;%s", (n_enable)? "true":"false"); } RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "attempting to modify audit log configuration"); if (n_enable) { // be sure to log audit log startup messages,if any RA::enable_audit_logging(n_enable); } RA::setup_audit_log(n_signing, n_signing != o_signing); if (n_enable && !o_enable) { RA::Audit(EV_AUDIT_LOG_STARTUP, AUDIT_MSG_FORMAT, "System", "Success", "audit function startup"); } else if (!n_enable && o_enable) { RA::Audit(EV_AUDIT_LOG_SHUTDOWN, AUDIT_MSG_FORMAT, "System", "Success", "audit function shutdown"); } RA::FlushAuditLogBuffer(); // sleep to ensure all logs written PR_Sleep(PR_SecondsToInterval(1)); if (!n_enable) { // turn off logging after all logs written RA::enable_audit_logging(n_enable); } need_update = 1; RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log config modified"); PR_snprintf((char *)msg, 512, "'%s' has modified audit log config: %s", userid, pString); RA::tdb_activity(rq->connection->client_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE); } char *logSigningInterval_str = get_post_field(post, "logSigningInterval", SHORT_LEN); int logSigningInterval = atoi(logSigningInterval_str); do_free(logSigningInterval_str); if ((logSigningInterval>=0) &&(logSigningInterval != RA::m_flush_interval)) { RA::SetFlushInterval(logSigningInterval); PR_snprintf((char *)msg, 512, "'%s' has modified the audit log signing interval to %d seconds", userid, logSigningInterval); RA::tdb_activity(rq->connection->client_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE); PR_snprintf(pString, 512, "logging.audit.flush.interval;;%d", logSigningInterval); RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log configuration modified"); } char *logSigningBufferSize_str = get_post_field(post, "logSigningBufferSize", SHORT_LEN); int logSigningBufferSize = atoi(logSigningBufferSize_str); do_free(logSigningBufferSize_str); if ((logSigningBufferSize >= 512) && (logSigningBufferSize != (int) RA::m_buffer_size)) { RA::SetBufferSize(logSigningBufferSize); PR_snprintf((char *)msg, 512, "'%s' has modified the audit log signing buffer size to %d bytes", userid, logSigningBufferSize); RA::tdb_activity(rq->connection->client_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE); PR_snprintf(pString, 512, "logging.audit.buffer.size;;%d", logSigningBufferSize); RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log configuration modified"); } char *nEvents_str = get_post_field(post, "nEvents", SHORT_LEN); int nEvents = atoi(nEvents_str); do_free(nEvents_str); char new_selected[MAX_INJECTION_SIZE]; int first_match = 1; for (int i=0; i< nEvents; i++) { char e_name[256]; PR_snprintf(e_name, 256, "event_%d", i); char *event = get_post_field(post, e_name, SHORT_LEN); if ((event != NULL) && RA::IsValidEvent(event)) { if (first_match != 1) { PL_strcat(new_selected, ","); } first_match = 0; PL_strcat(new_selected, event); } do_free(event); } if (PL_strcmp(new_selected, RA::m_signedAuditSelectedEvents) != 0) { need_update = 1; RA::update_signed_audit_selected_events(new_selected); PR_snprintf((char *)msg, 512, "'%s' has modified audit signing configuration", userid); RA::tdb_activity(rq->connection->client_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE); PR_snprintf(pLongString, 4096, "logging.audit.selected.events;;%s", new_selected); RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pLongString, "audit log configuration modified"); } if (need_update == 1) { tokendbDebug("Updating signed audit events in CS.cfg"); char error_msg[512]; status = RA::GetConfigStore()->Commit(true, error_msg, 512); if (status != 0) { tokendbDebug(error_msg); } } PR_snprintf(injection, MAX_INJECTION_SIZE, "/tus/tus?op=audit_admin&flash=Signed+Audit+configuration+has+been+updated"); do_free(buf); do_strfree(uri); do_strfree(query); rq->method = apr_pstrdup(rq->pool, "GET"); rq->method_number = M_GET; ap_internal_redirect_handler(injection, rq); return OK; } else if ( PL_strstr( query, "op=self_test") ) { tokendbDebug( "authorization for op=self_test\n" ); if (!is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "self_test", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_free(uri); do_free(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "self_test", "Success", "Tokendb user authorization"); PR_snprintf (injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%d%s%s%d%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var enabled = ", SelfTest::isOnDemandEnabled(), ";\n", "var critical = ", SelfTest::isOnDemandCritical(), ";\n"); if (SelfTest::nTests > 0) PL_strcat(injection, "var test_list = ["); for (int i = 0; i < SelfTest::nTests; i++) { RA::Debug( "mod_tokendb::mod_tokendb_handler", "test name: %s", SelfTest::TEST_NAMES[i]); if (i > 0) PL_strcat(injection, ", "); PL_strcat(injection, "\""); PL_strcat(injection, SelfTest::TEST_NAMES[i]); PL_strcat(injection, "\""); } if (SelfTest::nTests > 0) PL_strcat(injection, "];\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData(selfTestTemplate, injection); } else if ( PL_strstr( query, "op=run_self_test" ) ) { tokendbDebug( "authorization for run_self_test\n" ); if( ! is_admin ) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "run_self_test", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_free(uri); do_free(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "run_self_test", "Success", "Tokendb user authorization"); rc = SelfTest::runOnDemandSelfTests(); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%d%s%s%d%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var enabled = ", SelfTest::isOnDemandEnabled(), ";\n", "var result = \"", rc, "\";\n"); if (SelfTest::nTests > 0) PL_strcat(injection, "var test_list = ["); for (int i = 0; i < SelfTest::nTests; i++) { RA::Debug( "mod_tokendb::mod_tokendb_handler", "test name: %s", SelfTest::TEST_NAMES[i]); if (i > 0) PL_strcat(injection, ", "); PL_strcat(injection, "\""); PL_strcat(injection, SelfTest::TEST_NAMES[i]); PL_strcat(injection, "\""); } if (SelfTest::nTests > 0) PL_strcat(injection, "];\n"); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); PL_strcat(injection, JS_STOP); buf = getData( selfTestResultsTemplate, injection ); } else if( ( PL_strstr( query, "op=agent_select_config" ) ) ) { tokendbDebug( "authorization for op=agent_select_config\n" ); if (! is_agent) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_select_config", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_select_config", "Success", "Tokendb user authorization"); char *conf_type = NULL; char *disp_conf_type = NULL; conf_type = get_field(query, "type=", SHORT_LEN); if (conf_type == NULL) { error_out("Invalid Invocation: Type is NULL", "Type is NULL"); do_free(buf); do_strfree(uri); do_strfree(query); do_free(conf_type); return DONE; } // check if agent has permission to see this config parameter if (! agent_must_approve(conf_type)) { error_out("Invalid Invocation: Agent is not permitted to view this configuration item", "Agent is not permitted to view this configuration item"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } PR_snprintf( ( char * ) configname, 256, "target.%s.list", conf_type ); const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", conf_type ); disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", conf_type, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_list = \"", (conf_list != NULL)? conf_list : "", "\";\n"); do_free(conf_type); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed? PL_strcat(injection, JS_STOP); buf = getData( agentSelectConfigTemplate, injection ); } else if( ( PL_strstr( query, "op=select_config_parameter" ) ) ) { tokendbDebug( "authorization for op=select_config_parameter\n" ); if (! is_admin) { RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "select_config_parameter", "Failure", "Tokendb user authorization"); error_out("Authorization Failure", "Failed to authorize request"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "select_config_parameter", "Success", "Tokendb user authorization"); char *conf_type = NULL; conf_type = get_field(query, "type=", SHORT_LEN); if (conf_type == NULL) { error_out("Invalid Invocation: Type is NULL", "Type is NULL"); do_free(buf); do_strfree(uri); do_strfree(query); return DONE; } PR_snprintf( ( char * ) configname, 256, "target.%s.list", conf_type ); const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", conf_type ); const char *disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname ); PR_snprintf( injection, MAX_INJECTION_SIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START, "var uriBase = \"", uri, "\";\n", "var userid = \"", userid, "\";\n", "var conf_type = \"", conf_type, "\";\n", "var disp_conf_type = \"", disp_conf_type, "\";\n", "var conf_list = \"", (conf_list != NULL)? conf_list : "", "\";\n"); do_free(conf_type); // do_free(conf_list); add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed? PL_strcat(injection, JS_STOP); buf = getData( selectConfigTemplate, injection ); } if( buf != NULL ) { len = PL_strlen( buf ); ( void ) ap_rwrite( ( const void * ) buf, len, rq ); do_free(buf); } do_free(userid); do_strfree(uri); do_strfree(query); return OK; } /* _________________________________________________________________ ** ** Tokendb Module Command Phase ** _________________________________________________________________ */ static const char *mod_tokendb_get_config_path_file( cmd_parms *cmd, void *mconfig, const char *tokendbconf ) { if( cmd->path ) { ap_log_error( APLOG_MARK, APLOG_ERR, APLOG_MODULE_INDEX, 0, NULL, "The %s config param cannot be specified " "in a Directory section.", cmd->directive->directive ); } else { mod_tokendb_server_configuration *sc = NULL; /* Retrieve the Tokendb module. */ sc = ( ( mod_tokendb_server_configuration * ) ap_get_module_config( cmd->server->module_config, &MOD_TOKENDB_CONFIG_KEY ) ); /* Initialize the "Tokendb Configuration File" */ /* member of mod_tokendb_server_configuration. */ sc->Tokendb_Configuration_File = apr_pstrdup( cmd->pool, tokendbconf ); } return NULL; } static const command_rec mod_tokendb_config_cmds[] = { AP_INIT_TAKE1( MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER, ( const char*(*)() ) mod_tokendb_get_config_path_file, NULL, RSRC_CONF, MOD_TOKENDB_CONFIGURATION_FILE_USAGE ), { NULL } }; /* _________________________________________________________________ ** ** Tokendb Module Server Configuration Creation Phase ** _________________________________________________________________ */ /** * Create Tokendb module server configuration */ static void * mod_tokendb_config_server_create( apr_pool_t *p, server_rec *sv ) { /* Initialize all APR library routines. */ apr_initialize(); /* Create a memory pool for this server. */ mod_tokendb_server_configuration *sc = ( mod_tokendb_server_configuration * ) apr_pcalloc( p, ( apr_size_t ) sizeof( *sc ) ); /* Initialize all members of mod_tokendb_server_configuration. */ sc->Tokendb_Configuration_File = NULL; sc->enabled = MOD_TOKENDB_FALSE; return sc; } /* _________________________________________________________________ ** ** Tokendb Module Registration Phase ** _________________________________________________________________ */ static void mod_tokendb_register_hooks( apr_pool_t *p ) { static const char *const mod_tokendb_preloaded_modules[] = { "mod_nss.c", "mod_tps.cpp", NULL }; static const char *const mod_tokendb_postloaded_modules[] = { NULL }; ap_hook_post_config( mod_tokendb_initialize, mod_tokendb_preloaded_modules, mod_tokendb_postloaded_modules, APR_HOOK_MIDDLE ); ap_hook_handler( mod_tokendb_handler, mod_tokendb_preloaded_modules, mod_tokendb_postloaded_modules, APR_HOOK_MIDDLE ); } module TOKENDB_PUBLIC MOD_TOKENDB_CONFIG_KEY = { STANDARD20_MODULE_STUFF, NULL, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ mod_tokendb_config_server_create, /* create per-server config structures */ NULL, /* merge per-server config structures */ mod_tokendb_config_cmds, /* table of configuration directives */ mod_tokendb_register_hooks /* register hooks */ }; #ifdef __cplusplus } #endif