summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--common/certinfo.c2
-rw-r--r--common/eurephia_nullsafe.c10
-rw-r--r--common/eurephia_nullsafe.h23
-rw-r--r--common/eurephia_xml.c47
-rw-r--r--common/eurephia_xml.h3
-rw-r--r--database/eurephiadb.c21
-rw-r--r--database/eurephiadb_driver.h236
-rw-r--r--database/eurephiadb_mapping.c19
-rw-r--r--database/eurephiadb_mapping.h2
-rw-r--r--database/sqlite/CMakeLists.txt2
-rw-r--r--database/sqlite/administration/authentication.c (renamed from database/sqlite/administration.c)280
-rw-r--r--database/sqlite/administration/certificates.c5
-rw-r--r--database/sqlite/administration/firewalladmin.c2
-rw-r--r--database/sqlite/administration/lastlog.c2
-rw-r--r--database/sqlite/administration/useraccount.c438
-rw-r--r--database/sqlite/administration/usercerts.c6
-rw-r--r--database/sqlite/sqlite.c43
-rw-r--r--database/sqlite/sqlite.h23
-rw-r--r--eurephiadm/commands/users.c231
-rw-r--r--eurephiadm/eurephiadm.c147
-rw-r--r--utils/eurephia_init.c122
-rw-r--r--xslt/eurephiadm/certificates.xsl4
-rw-r--r--xslt/eurephiadm/lastlog.xsl4
-rw-r--r--xslt/eurephiadm/users.xsl16
25 files changed, 1032 insertions, 660 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2f22271..ee53ad4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,7 @@ PROJECT(eurephia C)
cmake_minimum_required(VERSION 2.6)
# Set the eurephia version
-ADD_DEFINITIONS(-DEUREPHIAVERSION="0.9.4_beta")
+ADD_DEFINITIONS(-DEUREPHIAVERSION="0.9.5_beta")
# eurephia parameters - boolean values
OPTION(DEBUG "Add more verbose debug information" OFF)
@@ -43,7 +43,7 @@ SET(XSLTROOT "/usr/local/share/eurephia/xslt" CACHE STRING "Root path for the XS
SET(CMAKE_INSTALL_PREFIX ${PREFIX})
# Default C compiler flags
-SET(CMAKE_C_FLAGS "-fno-delete-null-pointer-checks -g -Wall")
+SET(CMAKE_C_FLAGS "-fno-delete-null-pointer-checks -g -Wall -Wpointer-arith")
IF(GCOV)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
ENDIF(GCOV)
diff --git a/common/certinfo.c b/common/certinfo.c
index 1a7d532..f63b783 100644
--- a/common/certinfo.c
+++ b/common/certinfo.c
@@ -61,7 +61,7 @@ certinfo *parse_tlsid(const char *input) {
return NULL;
ret = (certinfo *) malloc_nullsafe(NULL, sizeof(certinfo)+2);
- bzero(&tmp, 130);
+ memset(&tmp, 0, 130);
mainp = strdup(input);
origptr = mainp;
diff --git a/common/eurephia_nullsafe.c b/common/eurephia_nullsafe.c
index f70b463..5f507c3 100644
--- a/common/eurephia_nullsafe.c
+++ b/common/eurephia_nullsafe.c
@@ -38,6 +38,12 @@
#include <eurephia_context.h>
#include <eurephia_log.h>
+#if __GNUC__ >= 3
+#define __malloc__ __attribute__((malloc))
+#else /* If not GCC 3 or newer, disable optimisations */
+#define __malloc__
+#endif
+
/**
* Internal function, should be called via the malloc_nullsafe() macro.
* This replaces the use of malloc() and memset(). This function uses calloc
@@ -51,7 +57,7 @@
*
* @return Returns a void pointer to the memory region on success, otherwise NULL
*/
-void *__malloc_nullsafe(eurephiaCTX *ctx, size_t sz, const char *file, int line) {
+__malloc__ void *_malloc_nullsafe(eurephiaCTX *ctx, size_t sz, const char *file, int line) {
void *buf = NULL;
buf = calloc(1, sz); /* Using calloc, also gives a zero'd memory region */
@@ -88,7 +94,7 @@ void *__malloc_nullsafe(eurephiaCTX *ctx, size_t sz, const char *file, int line)
* @param line debug info, which line in the file
*
*/
-void inline __free_nullsafe(eurephiaCTX *ctx, void *ptr, const char *file, int line) {
+void inline _free_nullsafe(eurephiaCTX *ctx, void *ptr, const char *file, int line) {
if( ptr == NULL ) {
return;
}
diff --git a/common/eurephia_nullsafe.h b/common/eurephia_nullsafe.h
index 5f6b58c..5249c19 100644
--- a/common/eurephia_nullsafe.h
+++ b/common/eurephia_nullsafe.h
@@ -59,6 +59,17 @@
/**
+ * Wrapper macro, which appends a string to a destination string without exceeding the size
+ * of the destination buffer.
+ *
+ * @param dest Pointer to the destination buffer
+ * @param src Pointer to the value being concatenated to the destination string.
+ * @param size Size of the destination buffer
+ */
+#define append_str(dest, src, size) strncat(dest, src, (size - strlen_nullsafe(dest)))
+
+
+/**
* strlen() wrapper. Returns the length of a string
*
* @param str Input string
@@ -69,10 +80,10 @@
-void *__malloc_nullsafe(eurephiaCTX *, size_t, const char *, int);
+void *_malloc_nullsafe(eurephiaCTX *, size_t, const char *, int);
/**
- * Front-end macro for the __malloc_nullsafe() function.
+ * Front-end macro for the _malloc_nullsafe() function.
*
* @param ctx eurephiaCTX (used for debugg logging)
* @param sz Size of the memory region wanted
@@ -80,19 +91,19 @@ void *__malloc_nullsafe(eurephiaCTX *, size_t, const char *, int);
* @return Returns a pointer to the memory region on success, otherwise NULL.
*
*/
-#define malloc_nullsafe(ctx, sz) __malloc_nullsafe(ctx, sz, __FILE__, __LINE__)
+#define malloc_nullsafe(ctx, sz) _malloc_nullsafe(ctx, sz, __FILE__, __LINE__)
-void inline __free_nullsafe(eurephiaCTX *ctx, void *ptr, const char *file, int line);
+void inline _free_nullsafe(eurephiaCTX *ctx, void *ptr, const char *file, int line);
/**
- * Front-end macro for the __free_nullsafe() function.
+ * Front-end macro for the __ree_nullsafe() function.
*
* @param ctx eurephiaCTX (used for debugg logging)
* @param ptr Pointer to the memory region being freed.
*
*/
-#define free_nullsafe(ctx, ptr) { __free_nullsafe(ctx, ptr, __FILE__, __LINE__); ptr = NULL; }
+#define free_nullsafe(ctx, ptr) { _free_nullsafe(ctx, ptr, __FILE__, __LINE__); ptr = NULL; }
/**
diff --git a/common/eurephia_xml.c b/common/eurephia_xml.c
index 91eacf4..dec397f 100644
--- a/common/eurephia_xml.c
+++ b/common/eurephia_xml.c
@@ -43,6 +43,27 @@
/**
+ * String replace in a xmlChar based string
+ *
+ * @param str xmlChar input string
+ * @param s search for this character
+ * @param r replace the character with this one
+ */
+void xmlReplaceChars(xmlChar *str, char s, char r) {
+ if( str != NULL ) {
+ xmlChar *ptr = str;
+
+ while( *ptr != '\0' ) {
+ if( *ptr == s ) {
+ *ptr = r;
+ }
+ ptr++;
+ }
+ }
+}
+
+
+/**
* Retrieves a given XML node attribute/property
*
* @param attr xmlAttr pointer from an xmlNode pointer.
@@ -81,7 +102,7 @@ xmlNode *xmlFindNode(xmlNode *node, const char *key) {
xmlNode *nptr = NULL;
xmlChar *x_key = NULL;
- if( node->children == NULL ) {
+ if( (node == NULL) || (node->children == NULL) ) {
return NULL;
}
@@ -236,6 +257,25 @@ xmlNode *eurephiaXML_getRoot(eurephiaCTX *ctx, xmlDoc *doc, const char *nodeset,
/**
+ * Checks if the given XML document is an eurephia ResultMsg XML document
+ *
+ * @param ctx eurephiaCTX
+ * @param resxml XML document to validate
+ *
+ * @return Returns 1 if the input XML document is a ResultMsg document. Otherwise 0
+ */
+unsigned int eurephiaXML_IsResultMsg(eurephiaCTX *ctx, xmlDoc *resxml) {
+ xmlNode *node = NULL;
+
+ assert( ctx != NULL );
+ if( resxml == NULL ) {
+ return 0;
+ }
+ node = eurephiaXML_getRoot(ctx, resxml, "Result", 1);
+ return (node != NULL ? 1 : 0);
+}
+
+/**
* Parses an eurephia Result XML document
*
* @param ctx eurephiaCTX
@@ -253,7 +293,10 @@ eurephiaRESULT *eurephiaXML_ParseResultMsg(eurephiaCTX *ctx, xmlDoc *resxml) {
xmlNode *res_n = NULL;
char *str = NULL;
- assert( (ctx != NULL) && (resxml != NULL) );
+ assert( ctx != NULL );
+ if( resxml == NULL ) {
+ return NULL;
+ }
res_n = eurephiaXML_getRoot(ctx, resxml, "Result", 1);
if( res_n == NULL) {
diff --git a/common/eurephia_xml.h b/common/eurephia_xml.h
index 614394a..083a881 100644
--- a/common/eurephia_xml.h
+++ b/common/eurephia_xml.h
@@ -62,6 +62,8 @@ typedef struct _eurephiaRESULT {
*/
#define foreach_xmlnode(start, itn) for( itn = start; itn != NULL; itn = itn->next )
+void xmlReplaceChars(xmlChar *str, char s, char r);
+
char *xmlGetAttrValue(xmlAttr *properties, const char *key);
xmlNode *xmlFindNode(xmlNode *node, const char *key);
@@ -69,6 +71,7 @@ int eurephiaXML_CreateDoc(eurephiaCTX *ctx, int format, const char *rootname, xm
xmlNode *eurephiaXML_getRoot(eurephiaCTX *ctx, xmlDoc *doc, const char *nodeset, int min_format);
xmlDoc *eurephiaXML_ResultMsg(eurephiaCTX *ctx, exmlResultType type, xmlNode *info_n, const char *fmt, ... );
+unsigned int eurephiaXML_IsResultMsg(eurephiaCTX *ctx, xmlDoc *resxml);
eurephiaRESULT *eurephiaXML_ParseResultMsg(eurephiaCTX *ctx, xmlDoc *resxml);
inline char *xmlExtractContent(xmlNode *n);
diff --git a/database/eurephiadb.c b/database/eurephiadb.c
index 6a12aea..05187af 100644
--- a/database/eurephiadb.c
+++ b/database/eurephiadb.c
@@ -108,27 +108,14 @@ int eDBlink_init(eurephiaCTX *ctx, const char *dbdriver, const int minver)
"to upgrade eurephia to take advantage of newer features in the eurephiaDB driver.");
case 2:
#ifdef ENABLE_EUREPHIADM
- eDBadminAuth = eGetSym(ctx, ctx->eurephia_driver, "eDBadminAuth");
- eDBadminValidateSession = eGetSym(ctx, ctx->eurephia_driver, "eDBadminValidateSession");
- eDBadminRegisterLogin = eGetSym(ctx, ctx->eurephia_driver, "eDBadminRegisterLogin");
- eDBadminLogout = eGetSym(ctx, ctx->eurephia_driver, "eDBadminLogout");
-
+ eDBadminAuthenticate = eGetSym(ctx, ctx->eurephia_driver, "eDBadminAuthenticate");
eDBadminConfiguration = eGetSym(ctx, ctx->eurephia_driver, "eDBadminConfiguration");
-
- eDBadminGetUserList = eGetSym(ctx, ctx->eurephia_driver, "eDBadminGetUserList");
- eDBadminGetUserInfo = eGetSym(ctx, ctx->eurephia_driver, "eDBadminGetUserInfo");
- eDBadminAddUser = eGetSym(ctx, ctx->eurephia_driver, "eDBadminAddUser");
- eDBadminUpdateUser = eGetSym(ctx, ctx->eurephia_driver, "eDBadminUpdateUser");
- eDBadminDeleteUser = eGetSym(ctx, ctx->eurephia_driver, "eDBadminDeleteUser");
-
+ eDBadminUserAccount = eGetSym(ctx, ctx->eurephia_driver, "eDBadminUserAccount");
eDBadminCertificate = eGetSym(ctx, ctx->eurephia_driver, "eDBadminCertificate");
-
eDBadminUserCertsLink = eGetSym(ctx, ctx->eurephia_driver, "eDBadminUserCertsLink");
-
eDBadminAccessLevel = eGetSym(ctx, ctx->eurephia_driver, "eDBadminAccessLevel");
-
- eDBadminFirewallProfiles = eGetSym(ctx, ctx->eurephia_driver, "eDBadminFirewallProfiles");
-
+ eDBadminFirewallProfiles = eGetSym(ctx, ctx->eurephia_driver,
+ "eDBadminFirewallProfiles");
eDBadminGetLastlog = eGetSym(ctx, ctx->eurephia_driver, "eDBadminGetLastlog");
eDBadminAttemptsLog = eGetSym(ctx, ctx->eurephia_driver, "eDBadminAttemptsLog");
eDBadminBlacklist = eGetSym(ctx, ctx->eurephia_driver, "eDBadminBlacklist");
diff --git a/database/eurephiadb_driver.h b/database/eurephiadb_driver.h
index e9c757c..ababa06 100644
--- a/database/eurephiadb_driver.h
+++ b/database/eurephiadb_driver.h
@@ -354,66 +354,58 @@ int (*eDBstore_session_value)(eurephiaCTX *ctx, eurephiaSESSION *session, int mo
/*
* functions which needs to exists in the API level 2
*/
+#ifdef HAVE_LIBXML2
/**
- * Authenticate a user for the administration interface. This interface do not
- * require any certificate validation and is intended for administration utilities
- * for eurephia. The eurephia context type must be either ECTX_ADMIN_CONSOLE or
- * ECTX_ADMIN_WEB.
+ * Authenticate users and sessions for the administration interface. The OpenVPN plug-in
+ * should never use this API.
*
* @version API version level 2
- * @param ctx eurephiaCTX - context used for administration task
- * @param req_access String (char *) containing the requested administration access level
- * @param uname username of the user being authenticated
- * @param pwd password from the user
- *
- * @return Returns users ID (uid) on success, otherwise 0
- */
-int (*eDBadminAuth) (eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd);
-
-
-/**
- * Validates a session key, to see if it still is valid (not auto-logged out or invalid session key)
- * and to check if they have access to a different access level. The eurephia context type must be
- * either ECTX_ADMIN_CONSOLE or ECTX_ADMIN_WEB.
+ * @param ctx eurephiaCTX
+ * @param qryxml eurephia XML document describing the operation to be done
*
- * @version API version level 2
- * @param ctx eurephiaCTX
- * @param sesskey String (char *) containing the session key to validate
- * @param req_access String (char *) containing the required administration access level
+ * XML document describing authentication of a user account
+ * @code
+ * <eurephia format="1">
+ * <Authenticate mode="user">
+ * <username>{username}</username>
+ * <password>{password}</password>
+ * <accesslevel>{accesslevel}</password>
+ * </Authenticate>
+ * </eurephia>
+ * @endcode
*
- * @return Returns 1 if the session is valid and the user have the needed privileges,
- * otherwise 0 is returned.
- */
-int (*eDBadminValidateSession) (eurephiaCTX *ctx, const char *sesskey, const char *req_access);
-
-
-/**
- * Registers the user as logged in after a successful authentication. The user must
- * be registered as logged in to have a valid session.
+ * XML document for authenticating and validating a user session to a specific access level
+ * @code
+ * <eurephia format="1">
+ * <Authenticate mode="session">
+ * <sessionkey>{session key}</sessionkey>
+ * <accesslevel>{accesslevel}</password>
+ * </Authenticate>
+ * </eurephia>
+ * @endcode
*
- * @version API version level 2
- * @param ctx eurephiaCTX
- * @param session eurephiaSESSION
+ * XML docuument to register the user as logged in
+ * @code
+ * <eurephia format="1">
+ * <Register mode="login" uid="{uid}">{session key}</Register>
+ * </eurephia>
+ * @endcode
*
- * @return Returns 1 on success, otherwise 0
- */
-int (*eDBadminRegisterLogin) (eurephiaCTX *ctx, eurephiaSESSION *session);
-
-
-/**
- * Registers a session as logged out. This will require the user to do a new authentication
- * on next access via the administration interface
+ * XML docuument to register the user as logged out
+ * @code
+ * <eurephia format="1">
+ * <Register mode="logout">{session key}</Register>
+ * </eurephia>
+ * @endcode
*
- * @version API version level 2
- * @param ctx eurephiaCTX
- * @param sessionkey String (char *) containing the session key
+ * @return Returns a valid eurephia ResultMsg XML document with the result. On fatal errors,
+ * NULL is returned. When a username/password authentication is done, the user id of the
+ * user will be returned in the details part of the ResultMsg.
*
- * @return Returns 1 on success, otherwise 0
*/
-int (*eDBadminLogout) (eurephiaCTX *ctx, const char *sessionkey);
+xmlDoc *(*eDBadminAuthenticate) (eurephiaCTX *ctx, xmlDoc *qryxml);
-#ifdef HAVE_LIBXML2
/**
* Set or delete configuration parameters in the database. This operation will
* also update the in-memory copy of the configuration
@@ -439,129 +431,47 @@ xmlDoc *(*eDBadminConfiguration)(eurephiaCTX *ctx, xmlDoc *cfgxml);
/**
- * Retrieve a list over all users in the database.
- *
- * @version API version level 2
- * @param ctx eurephiaCTX
- * @param sortkeys String containing the sort order of the fields
- *
- * @return Returns an XML document on success with all users, otherwise NULL
- * @see eurephiaXML_CreateDoc(), eurephiaXML_getRoot()
- */
-xmlDoc *(*eDBadminGetUserList) (eurephiaCTX *ctx, const char *sortkeys);
-
-
-/**
- * This function will search up a user, based on information given in a fieldMapping structure.
- * It will return an XML document containing the user information requested, controlled by the
- * infoType flag. These flags are defined in eurephiadb_driver.h
- *
- * @version API version level 2
- * @param ctx eurephiaCTX
- * @param infoType Flags of what information to extract. Valid flags are: USERINFO_user,
- * USERINFO_certs, USERINFO_lastlog, USERINFO_attempts, USERINFO_blacklist.
- * These flags can be bit-wise OR'ed together to extract more information
- * at once.
- *
- * @param srch XML document describing the search criteria
- *
- * Skeleton of an XML search document
- * @code
- * <eurephia format="1">
- * <fieldMapping table="users">
- * <{search field}>{search value}</{search field}>
- * </fieldMapping>
- * </eurephia>
- * @endcode
- *
- * @return Returns an XML document containing the requested user information on success, otherwise
- * NULL is returned.
- * @see eurephiaXML_CreateDoc(), eurephiaXML_getRoot()
- * @see USERINFO_user, USERINFO_certs, USERINFO_lastlog, USERINFO_attempts, USERINFO_blacklist
- */
-xmlDoc *(*eDBadminGetUserInfo) (eurephiaCTX *ctx, int infoType, xmlDoc *srch);
-
-
-/**
- * This function will add a user to the openvpn_users table, based on the
- * XML document given.
- *
- * @version API version level 2
- * @param ctx eurephiaCTX
- * @param userinfo XML document containing information about the new user
- *
- * Skeleton of an XML document for adding a new user
- * @code
- * <eurephia format="1">
- * <add_user>
- * <fieldMapping table="users">
- * <username>{user name}</username>
- * <password pwhash="{none|sha512}">{password}</password>
- * </fieldMapping>
- * </add_user>
- * </eurephia>
- * @endcode
- *
- * The password tag can use either a clear-text password (by setting pwhash="none") or a pre-hashed
- * SHA512 password (by setting pwhash="sha512"). Beware that the SHA512 hash must be hashed with
- * the eurephia_pwd_crypt() function.
- *
- * @return Returns the user ID (uid) of the new user account on success, otherwise -1 is returned.
- * @see eurephiaXML_CreateDoc(), eurephia_pwd_crypt()
- */
-int (*eDBadminAddUser) (eurephiaCTX *ctx, xmlDoc *userinfo);
-
-
-/**
- * This function will update a user account based on the XML document sent in as a parameter.
- * The function will double check that the uid in the argument list and the uid in the XML
- * document is coherent.
+ * Function for view, add, update or delete user accounts
*
- * @version API version level 2
* @param ctx eurephiaCTX
- * @param uid Numeric user ID of the user account being updated
- * @param userinfo XML document containing the new information for the user account
+ * @param qryxml XML document with information about the operation
*
- * Skeleton of an XML document updating a user
* @code
* <eurephia format="1">
- * <update_user uid="{uid}">
- * <fieldMapping table="users">
- * <{field name}>{new value}</{field name}>
- * </fieldMapping>
- * </update_user>
+ * <UserAccount mode="{view|add|update|delete}" [uid="{uid}"]>
+ * <fieldMapping table="users">
+ * <{field name}>{field value}</{field name}>
+ * ...
+ * <{field name}>{field value}</{field name}>
+ * </fieldMapping>
+ * [<sortkeys>{field name}[, {field name}...]</sortkeys>]
+ * [<extractFlags>{extract value (int)}</extractFlags>]
+ * </UserAccount>
* </eurephia>
* @endcode
- * @remarks Beware that the uid attribute in the update_user tag must be the same user ID given as
- * argument to the function.
+ * Valid field names are: uid, username, password, activated, deactivated, lastaccess
*
- * @return Returns 1 on success, otherwise 0.
- * @see eurephiaXML_CreateDoc()
- */
-int (*eDBadminUpdateUser) (eurephiaCTX *ctx, const int uid, xmlDoc *userinfo);
-
-
-/**
- * This function will delete a user to the openvpn_users table, based on the
- * XML document given.
+ * If no field names and values are given in "view" mode, all user accounts will be returned. Adding
+ * field name tags will narrow down the query.
*
- * @version API version level 2
- * @param ctx eurephiaCTX
- * @param uid Numeric user ID of the user account being updated
- * @param userinfo XML document containing information about the account which is going to be deleted
+ * For "add" mode, username and password tag is required. For the password tag, the attribute "pwhash"
+ * can be given to indicate what kind of hashing the value provided is using. If this is not set, the
+ * password value is expected to come in clear text and will be hashed automatically with a SHA512
+ * algorithm.
*
- * @code
- * <eurephia format="1">
- * <delete_user uid="{uid}"/>
- * </eurephia>
- * @endcode
- * @remarks The uid of the account to be deleted must also be sent
- * as a separate parameter, as a security feature
+ * For the "update" mode, the uid attribute in the UserAccount tag is required. This will be the
+ * key for which record to update. The values being updated need to be set in the fieldMapping tags.
*
- * @return Returns 1 on success, otherwise 0.
- * @see eurephiaXML_CreateDoc()
+ * For "delete" mode, the "uid" attribute in the UserAccount tag is required. This mode will also ignore
+ * any fieldMapping tags.
+ *
+ * @return When mode is "view", it will return an XML document with user account information on success.
+ * On errors in "view" mode or the other modes in general, it will return an eurephia ResultMsg
+ * XML document with the result of the operation, or NULL on fatal errors.
+ *
+ * @see eurephiaXML_CreateDoc(), eurephiaXML_ParseResultMsg(), eurephiaXML_getRoot()
*/
-int (*eDBadminDeleteUser) (eurephiaCTX *ctx, const int uid, xmlDoc *userinfo);
+xmlDoc *(*eDBadminUserAccount) (eurephiaCTX *ctx, xmlDoc *qryxml);
/**
@@ -569,7 +479,7 @@ int (*eDBadminDeleteUser) (eurephiaCTX *ctx, const int uid, xmlDoc *userinfo);
*
* @version API version level 2
* @param ctx eurephiaCTX
- * @param qryxml XML document with the certificate information to be deleted
+ * @param qryxml XML document with information about the operation
*
* Skeleton of an XML document used for eDBadminCertificate()
* @code
@@ -580,13 +490,17 @@ int (*eDBadminDeleteUser) (eurephiaCTX *ctx, const int uid, xmlDoc *userinfo);
* ...
* <{field name}>{field value}</{field name}>
* </fieldMapping>
- * </certificate_info>
+ * [<sortkeys>{field name}[, {field name}...]</sortkeys>]
+ * </certificates>
* </eurephia>
* @endcode
* Valid field names are: depth, digest, common_name, org, email and certid.
* For list and delete mode, all field names can be used to narrow the search query.
* In register mode all fields are required, except certid which must not be given.
*
+ * The sortkeys tag will only be used in list mode, and it takes a list of comma separated
+ * field names.
+ *
* @return When mode is "list", it will return an XML document with all found certificates, otherwise NULL.
* If mode is "register" or "delete" an eurephia ResultMsg XML document will be returned with
* the result of the operation, or NULL on fatal errors.
diff --git a/database/eurephiadb_mapping.c b/database/eurephiadb_mapping.c
index 3a2513a..26b9dd7 100644
--- a/database/eurephiadb_mapping.c
+++ b/database/eurephiadb_mapping.c
@@ -352,9 +352,8 @@ eDBfieldMap *eDBxmlMapping(eurephiaCTX *ctx, eDBfieldMap *dbmap, const char *tbl
* @return Returns a comma separated string with translated field names on success, otherwise NULL.
* @remark The resulting pointer is pointing at a static char pointer and should not be freed.
*/
-char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str) {
- eDBfieldMap *sk_map = NULL, *ptr1 = NULL;
- int i;
+const char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str) {
+ eDBfieldMap *sk_map = NULL, *ptr1 = NULL, *tfmp = NULL;
char *cp = NULL, *tok = NULL, *delims = ",";
static char sortkeys[8194];
@@ -378,10 +377,14 @@ char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str) {
// If we find the the field in the unified mapping table ...
if( strcmp(tok, ptr1->field_name) == 0 ) {
// look up the proper field name for the current database
- for( i = 0; tfmap[i].field_type != FIELD_NONE; i++ ) {
- if( ptr1->field_id == tfmap[i].field_id ) {
- strncat(sortkeys, tfmap[i].field_name, (8192-strlen(sortkeys)-2));
- strcat(sortkeys,",");
+ for( tfmp = tfmap; tfmp != NULL; tfmp = tfmp->next ) {
+ if( ptr1->field_id == tfmp->field_id ) {
+ if( tfmp->table_alias != NULL ) {
+ append_str(sortkeys, tfmp->table_alias, 8192);
+ append_str(sortkeys, ".", 8192);
+ }
+ append_str(sortkeys, tfmp->field_name, 8192);
+ append_str(sortkeys, ",", 8192);
}
}
}
@@ -392,7 +395,7 @@ char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str) {
sortkeys[strlen(sortkeys)-1] = '\0';
eDBfreeMapping(sk_map);
- return sortkeys;
+ return (strlen_nullsafe(sortkeys) > 0 ? sortkeys : NULL);
}
diff --git a/database/eurephiadb_mapping.h b/database/eurephiadb_mapping.h
index 262231e..37c9f44 100644
--- a/database/eurephiadb_mapping.h
+++ b/database/eurephiadb_mapping.h
@@ -262,7 +262,7 @@ static eDBfieldMap eTblMap_fwprofiles[] = {
void eDBfreeMapping(eDBfieldMap *p);
eDBfieldMap *eDBxmlMapping(eurephiaCTX *ctx, eDBfieldMap *dbmap, const char *tblalias, xmlNode *fmap_n);
-char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str);
+const char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str);
long int eDBmappingFieldsPresent(eDBfieldMap *map);
const char *eDBmappingGetValue(eDBfieldMap *map, long field_id);
diff --git a/database/sqlite/CMakeLists.txt b/database/sqlite/CMakeLists.txt
index 44f5c99..463aee7 100644
--- a/database/sqlite/CMakeLists.txt
+++ b/database/sqlite/CMakeLists.txt
@@ -47,7 +47,7 @@ SET(edb_sqlite_SRC
IF(ADMIN_ENABLED)
SET(edb_sqlite_SRC ${edb_sqlite_SRC}
- administration.c
+ administration/authentication.c
administration/firewalladmin.c
administration/attempts.c
administration/blacklist.c
diff --git a/database/sqlite/administration.c b/database/sqlite/administration/authentication.c
index 04dbe6e..75ad991 100644
--- a/database/sqlite/administration.c
+++ b/database/sqlite/administration/authentication.c
@@ -20,12 +20,11 @@
*/
/**
- * @file administration.c
+ * @file authentication.c
* @author David Sommerseth <dazo@users.sourceforge.net>
* @date 2008-12-03
*
- * @brief Functions needed for the administration interface. This file
- * primarily takes care of user authentication via the administration API
+ * @brief Functions used for authentication of administration sessions.
*
*/
@@ -61,7 +60,7 @@
#endif
#include <eurephiadb_driver.h>
-#include "sqlite.h"
+#include "../sqlite.h"
#if (DRIVERAPIVERSION > 1) || defined(DOXYGEN)
/*
@@ -69,38 +68,30 @@
*
*/
-/**
- * Internal function. String replace in a xmlChar based string
- *
- * @param str xmlChar input string
- * @param s search for this character
- * @param r replace the character with this one
- */
-void xmlReplaceChars(xmlChar *str, char s, char r) {
- if( str != NULL ) {
- xmlChar *ptr = str;
-
- while( *ptr != '\0' ) {
- if( *ptr == s ) {
- *ptr = r;
- }
- ptr++;
- }
- }
-}
-
/**
- * @copydoc eDBadminAuth()
+ * Authenticate a user for the administration interface. This interface do not
+ * require any certificate validation and is intended for administration utilities
+ * for eurephia. The eurephia context type must be either ECTX_ADMIN_CONSOLE or
+ * ECTX_ADMIN_WEB.
+ *
+ * @param ctx eurephiaCTX - context used for administration task
+ * @param req_access String containing the requested administration access level
+ * @param uname username of the user being authenticated
+ * @param pwd password from the user
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd) {
+static xmlDoc *auth_user(eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd) {
+ xmlDoc *res_d = NULL;
+ xmlNode *info_n = NULL;
dbresult *res = NULL;
char *crpwd = NULL, *dbpwd = NULL;
- char *activated = NULL, *deactivated = NULL, *blid = NULL;
- int uid = -1, access = 0;
+ char *activated = NULL, *deactivated = NULL, *blid = NULL, *uid = NULL;
+ int access = 0;
char interface;
- DEBUG(ctx, 20, "Function call: eDBadminAuth(ctx, '%s, '%s', 'xxxxxxxx')", req_access, uname);
+ DEBUG(ctx, 21, "Function call: auth_user(ctx, '%s, '%s', 'xxxxxxxx')", req_access, uname);
assert(ctx != NULL);
@@ -113,12 +104,13 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
- return 0;
+ return NULL;
}
if( (strlen_nullsafe(uname) < 4) || (strlen_nullsafe(pwd) < 4) ) {
- eurephia_log(ctx, LOG_WARNING, 0, "User name and/or password is either null or less than 4 bytes");
- return 0;
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "Username and/or password is either null or less than 4 bytes");
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Username or password is too short");
}
//
@@ -134,7 +126,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
if( res == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not authenticate user against the database");
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( sqlite_get_numtuples(res) == 1 ) {
@@ -142,31 +134,31 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
deactivated = sqlite_get_value(res, 0, 1);
blid = sqlite_get_value(res, 0, 2);
dbpwd = sqlite_get_value(res, 0, 3);
- uid = atoi_nullsafe(sqlite_get_value(res, 0, 4));
+ uid = strdup_nullsafe(sqlite_get_value(res, 0, 4));
if( blid != NULL ) {
eurephia_log(ctx, LOG_WARNING, 0,
- "Your user account is BLACKLISTED. You have no access.");
+ "User account '%s' is BLACKLISTED. You have no access.", uname);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( activated == NULL ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is not yet activated.");
+ eurephia_log(ctx, LOG_WARNING, 0, "User account '%s' is not yet activated.", uname);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( deactivated != NULL ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is deactivated.");
+ eurephia_log(ctx, LOG_WARNING, 0, "User account '%s' is deactivated.", uname);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( dbpwd == NULL ) {
eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. DB error.");
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
} else {
int pwdok = 0;
// Verify the password
@@ -179,7 +171,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed.");
sleep(2);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
}
sqlite_free_results(res);
@@ -190,40 +182,56 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
res = sqlite_query(ctx,
"SELECT (count(*) = 1) AS access "
" FROM eurephia_adminaccess"
- " WHERE uid = '%i' AND interface = '%c' AND access = '%q'",
+ " WHERE uid = '%q' AND interface = '%c' AND access = '%q'",
uid, interface, req_access);
+
if( res == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not check access level");
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,"Failed to validate access level");
}
access = atoi_nullsafe(sqlite_get_value(res, 0, 0));
sqlite_free_results(res);
if( access == 0 ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your account is lacking privileges for this operation");
- return 0;
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "User account '%s' is lacking privileges for this operation", uname);
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
} else {
eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. No unique records found.");
sqlite_free_results(res);
sleep(2);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
// If we reach this place, authentication was successful. Return users uid
- return uid;
+ info_n = xmlNewNode(NULL, (xmlChar *) "UserAccount");
+ assert( info_n != NULL );
+ xmlNewProp(info_n, (xmlChar *) "uid", (xmlChar *) uid);
+ res_d = eurephiaXML_ResultMsg(ctx, exmlRESULT, info_n, "Successful authentication");
+ xmlFreeNode(info_n);
+ free_nullsafe(ctx, uid);
+ return res_d;
}
/**
- * @copydoc eDBadminValidateSession()
+ * Validates a session key, to see if it still is valid (not auto-logged out or invalid session key)
+ * and to check if they have access to a different access level. The eurephia context type must be
+ * either ECTX_ADMIN_CONSOLE or ECTX_ADMIN_WEB.
+ *
+ * @param ctx eurephiaCTX
+ * @param sesskey String containing the session key to validate
+ * @param req_access String containing the required administration access level
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *req_access) {
+static xmlDoc *auth_session(eurephiaCTX *ctx, const char *sesskey, const char *req_access) {
dbresult *res = NULL;
int valid = 0, access = 0, expire_time = 0;
char interface;
- DEBUG(ctx, 20, "Function call: eDBadminValidateSession(ctx, '%s, '%s')", sesskey, req_access);
+ DEBUG(ctx, 21, "Function call: auth_session(ctx, '%s, '%s')", sesskey, req_access);
assert( (ctx != NULL) && (sesskey != NULL) );
switch( ctx->context_type ) {
@@ -235,12 +243,13 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
- return 0;
+ return NULL;
}
// Check if the session is still valid (not expired) and that this session are allowed to access
// the requested access level.
- expire_time = (60 * atoi_nullsafe(defaultValue(eGet_value(ctx->dbc->config, "eurephiadmin_autologout"),
+ expire_time = (60 * atoi_nullsafe(defaultValue(eGet_value(ctx->dbc->config,
+ "eurephiadmin_autologout"),
"10")
)
);
@@ -251,12 +260,13 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
" LEFT JOIN eurephia_adminaccess USING(uid,interface)"
" WHERE status IN (1,2)"
" AND sessionkey = '%q'"
- " AND access = '%q'",
- expire_time, sesskey, req_access);
+ " AND access = '%q'"
+ " AND interface = '%c'",
+ expire_time, sesskey, req_access, interface);
if( (res == NULL) ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not validate session");
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Session authentication failed");
}
valid = (atoi_nullsafe(sqlite_get_value(res, 0, 0)) == 0);
@@ -276,7 +286,6 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
} else {
// If not valid, register session as auto-logged out
-
res = sqlite_query(ctx,
"UPDATE eurephia_adminlog"
" SET logout = CURRENT_TIMESTAMP, status = %i"
@@ -293,29 +302,41 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
if( res == NULL ) {
eurephia_log(ctx, LOG_ERROR, 0,
"Could not delete session variables (%s))", sesskey);
- return 0;
+ } else if( !access ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "User account is lacking privileges");
}
sqlite_free_results(res);
+ }
- if( !access ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is lacking privileges");
- }
+ if (valid && access) {
+ return eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Session authenticated");
+ } else {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Session authentication failed");
}
- return (valid && access);
}
/**
- * @copydoc eDBadminRegisterLogin()
+ * Registers the user as logged in after a successful authentication. The user must
+ * be registered as logged in to have a valid session.
+ *
+ * @param ctx eurephiaCTX
+ * @param uid Numeric value if the user ID the session belongs to
+ * @param sesskey String containing the session key
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminRegisterLogin(eurephiaCTX *ctx, eurephiaSESSION *session) {
+static xmlDoc *register_login(eurephiaCTX *ctx, const int uid, const char *sesskey) {
dbresult *res = NULL;
char interface;
- int uid;
- DEBUG(ctx, 20, "Function call: eDBadminRegisterLogin(ctx, {session}'%s')", session->sessionkey);
- assert((ctx != NULL) && (session != NULL));
+ DEBUG(ctx, 21, "Function call: register_login(ctx, %i, '%s')", uid, sesskey);
+ assert( ctx != NULL );
+
+ if( (sesskey == NULL) || (uid < 1) ) {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Invalid data for login registration");
+ }
switch( ctx->context_type ) {
case ECTX_ADMIN_CONSOLE:
@@ -324,38 +345,44 @@ int eDBadminRegisterLogin(eurephiaCTX *ctx, eurephiaSESSION *session) {
interface = 'W'; break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
- return 0;
+ return NULL;
}
// Register login into eurephia_adminlog ... uid, login, interface, sessionkey
- uid = atoi_nullsafe(eGet_value(session->sessvals, "uid"));
res = sqlite_query(ctx,
"INSERT INTO eurephia_adminlog "
" (uid, interface, status, login, last_action, sessionkey) "
"VALUES ('%i','%c',1,CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '%q')",
- uid, interface, session->sessionkey);
+ uid, interface, sesskey);
if( !res ) {
- eurephia_log(ctx, LOG_FATAL, 0, "Could not manage to register the session in the database");
- return 0;
+ eurephia_log(ctx, LOG_FATAL, 0, "Failed to register the session in the database");
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to register the session in the database");
}
sqlite_free_results(res);
- return 1;
+ return eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Session is registered as logged in");
}
/**
- * @copydoc eDBadminLogout()
+ * Registers a session as logged out. This will require the user to do a new authentication
+ * on next access via the administration interface
+ *
+ * @param ctx eurephiaCTX
+ * @param sessionkey String containing the session key
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminLogout(eurephiaCTX *ctx, const char *sessionkey) {
+static xmlDoc *register_logout(eurephiaCTX *ctx, const char *sessionkey) {
dbresult *res = NULL;
- DEBUG(ctx, 20, "Function call: eDBadminLogout(ctx, '%s')", sessionkey);
+ DEBUG(ctx, 21, "Function call: register_logout(ctx, '%s')", sessionkey);
assert((ctx != NULL) && (sessionkey != NULL));
if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
eurephia_log(ctx, LOG_CRITICAL, 0,
"eurephia admin function call attempted with wrong context type");
- return 0;
+ return NULL;
}
// Update session as logged out
@@ -364,21 +391,108 @@ int eDBadminLogout(eurephiaCTX *ctx, const char *sessionkey) {
" SET logout = CURRENT_TIMESTAMP, status = 3"
" WHERE sessionkey = '%q'",
sessionkey);
- if( !res ) {
- eurephia_log(ctx, LOG_FATAL, 0, "Could not manage to register the session as logged out");
- return 0;
+ if( !res || (sqlite_get_affected_rows(res) == 0) ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Failed to register the session as logged out (updated %i rows)",
+ sqlite_get_affected_rows(res));
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to register the session as logged out");
}
sqlite_free_results(res);
// Delete session variables
res = sqlite_query(ctx, "DELETE FROM openvpn_sessions WHERE sessionkey = '%q'", sessionkey);
- if( res == NULL ) {
+ if( !res || (sqlite_get_affected_rows(res) == 0) ) {
eurephia_log(ctx, LOG_ERROR, 0,
"Could not delete session variables (%s))", sessionkey);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Could not delete session variables (%s))", sessionkey);
}
sqlite_free_results(res);
- return 1;
+ return eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Session is logged out");
+}
+
+
+/**
+ * @copydoc eDBadminAuthenticate()
+ */
+xmlDoc *eDBadminAuthenticate(eurephiaCTX *ctx, xmlDoc *qryxml) {
+ xmlDoc *res_d = NULL;
+ xmlNode *qry_n = NULL;
+ char *mode = NULL;
+ int type = 0;
+
+ DEBUG(ctx, 20, "Function call: eDBadminAuthenticate(ctx, xmlDoc)");
+ assert( (ctx != NULL) && (qryxml != NULL) );
+
+ if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "eurephia admin function call attempted with wrong context type");
+ return NULL;
+ }
+
+ qry_n = eurephiaXML_getRoot(ctx, qryxml, "Authenticate", 1);
+ if( qry_n != NULL ) {
+ type = 1;
+ goto accept;
+ }
+
+ qry_n = eurephiaXML_getRoot(ctx, qryxml, "Register", 1);
+ if( qry_n != NULL ) {
+ type = 2;
+ goto accept;
+ }
+
+ eurephia_log(ctx, LOG_ERROR, 0, "Could not find a valid XML request for eDBadminAuthenticate()");
+ return NULL;
+
+ accept:
+ mode = xmlGetAttrValue(qry_n->properties, "mode");
+ if( mode == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Invalid authentication request");
+ return NULL;
+ }
+
+ switch( type ) {
+ case 1: // Authenticate tag
+ if( strcmp(mode, "user") == 0 ) {
+ // const char *req_access, const char *uname, const char *pwd
+ const char *reqacc = NULL, *uname = NULL, *pwd = NULL;
+ uname = xmlGetNodeContent(qry_n, "username");
+ pwd = xmlGetNodeContent(qry_n, "password");
+ reqacc = xmlGetNodeContent(qry_n, "accesslevel");
+ res_d = auth_user(ctx, reqacc, uname, pwd);
+ } else if ( strcmp(mode, "session") == 0 ) {
+ const char *sesskey = NULL, *reqacc = NULL;
+ sesskey = xmlGetNodeContent(qry_n, "sessionkey");
+ reqacc = xmlGetNodeContent(qry_n, "accesslevel");
+ res_d = auth_session(ctx, sesskey, reqacc);
+ }
+ break;
+
+ case 2: // Register tag
+ if( strcmp(mode, "login") == 0 ) {
+ const char *sesskey = NULL;
+ unsigned int uid = 0;
+
+ uid = atoi_nullsafe(xmlGetAttrValue(qry_n->properties, "uid"));
+ sesskey = xmlExtractContent(qry_n);
+ res_d = register_login(ctx, uid, sesskey);
+ } else if( strcmp(mode, "logout") == 0 ) {
+ const char *sesskey = NULL;
+
+ sesskey = xmlExtractContent(qry_n);
+ res_d = register_logout(ctx, sesskey);
+ }
+ break;
+
+ default:
+ eurephia_log(ctx, LOG_FATAL, 0, "The unthinkable has just happened (type %i)", type);
+ res_d = NULL;
+ break;
+ }
+ return res_d;
}
+
#endif
diff --git a/database/sqlite/administration/certificates.c b/database/sqlite/administration/certificates.c
index 53b50c2..b64aa07 100644
--- a/database/sqlite/administration/certificates.c
+++ b/database/sqlite/administration/certificates.c
@@ -55,7 +55,6 @@
#define FMAP_CERTS /**< fieldmapping.h: Include declaration of tbl_sqlite_certs */
#include "../fieldmapping.h"
-void xmlReplaceChars(xmlChar *str, char s, char r);
/**
* Internal function. Retrieves info about one or more certificates
@@ -267,8 +266,8 @@ xmlDoc *eDBadminCertificate(eurephiaCTX *ctx, xmlDoc *qryxml) {
fmap = eDBxmlMapping(ctx, tbl_sqlite_certs, NULL, fieldmap_n);
if( strcmp(mode, "list") == 0 ) {
- char *sortkeys = xmlGetNodeContent(root_n, "sortkeys");
- resxml = certificate_list(ctx, fmap, eDBmkSortKeyString(tbl_sqlite_certs, sortkeys));
+ char *sortkeys = xmlGetNodeContent(root_n, "sortkeys");
+ resxml = certificate_list(ctx, fmap, eDBmkSortKeyString(fmap, sortkeys));
} else if( strcmp(mode, "register") == 0 ) {
resxml = certificate_add(ctx, fmap);
} else if( strcmp(mode, "delete") == 0 ) {
diff --git a/database/sqlite/administration/firewalladmin.c b/database/sqlite/administration/firewalladmin.c
index 6c6b91e..fdebccb 100644
--- a/database/sqlite/administration/firewalladmin.c
+++ b/database/sqlite/administration/firewalladmin.c
@@ -58,8 +58,6 @@
#define FMAP_OVPNACCESSES
#include "../fieldmapping.h"
-void xmlReplaceChars(xmlChar *str, char s, char r);
-
/**
* Internal function. Queries the database for a list of user-certificate links
diff --git a/database/sqlite/administration/lastlog.c b/database/sqlite/administration/lastlog.c
index 15703ce..e850d94 100644
--- a/database/sqlite/administration/lastlog.c
+++ b/database/sqlite/administration/lastlog.c
@@ -54,8 +54,6 @@
#define FMAP_LASTLOG /**< fieldmapping.h: Include declaration of tbl_sqlite_lastlog */
#include "../fieldmapping.h"
-void xmlReplaceChars(xmlChar *str, char s, char r);
-
/**
* @copydoc eDBadminGetLastlog()
diff --git a/database/sqlite/administration/useraccount.c b/database/sqlite/administration/useraccount.c
index 4f44789..b0613a5 100644
--- a/database/sqlite/administration/useraccount.c
+++ b/database/sqlite/administration/useraccount.c
@@ -57,63 +57,6 @@
#include "../fieldmapping.h"
-void xmlReplaceChars(xmlChar *str, char s, char r);
-
-
-/**
- * @copydoc eDBadminGetUserList()
- */
-xmlDoc *eDBadminGetUserList(eurephiaCTX *ctx, const char *sortkeys) {
- xmlDoc *userlist = NULL;
- xmlNode *root_n = NULL, *user_n = NULL;
- dbresult *res = NULL;
- char *dbsort = NULL, tmp[34];
- int i = 0;
-
- DEBUG(ctx, 20, "Function call: eDBadminGetUserList(ctx, '%s')", sortkeys);
- assert((ctx != NULL) && (ctx->dbc != 0));
-
- if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
- eurephia_log(ctx, LOG_CRITICAL, 0,
- "eurephia admin function call attempted with wrong context type");
- return NULL;
- }
-
- // Convert the input sort keys to the proper database field names
- dbsort = eDBmkSortKeyString(tbl_sqlite_users, sortkeys);
-
- // Query database for all users
- res = sqlite_query(ctx,
- "SELECT username, activated, deactivated, last_accessed, uid"
- " FROM openvpn_users "
- "ORDER BY %s", (sortkeys != NULL ? dbsort : "uid"));
- if( res == NULL ) {
- eurephia_log(ctx, LOG_ERROR, 0, "Error querying the user database");
- return NULL;
- }
-
- // Prepare a list with all users
- memset(&tmp, 0, 34);
- eurephiaXML_CreateDoc(ctx, 1, "userlist", &userlist, &root_n);
- snprintf(tmp, 32, "%i", sqlite_get_numtuples(res));
- xmlNewProp(root_n, (xmlChar *)"usercount", (xmlChar *)tmp);
-
- // Register all records
- for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
- user_n = xmlNewChild(root_n, NULL, (xmlChar *)"user", NULL);
- sqlite_xml_value(user_n, XML_ATTR, "uid", res, i, 4);
- sqlite_xml_value(user_n, XML_NODE, "username", res, i, 0);
- sqlite_xml_value(user_n, XML_NODE, "activated", res, i, 1);
- sqlite_xml_value(user_n, XML_NODE, "deactivated", res, i, 2);
- sqlite_xml_value(user_n, XML_NODE, "last_accessed", res, i, 3);
- }
- sqlite_free_results(res);
-
- // Return a user list
- return userlist;
-}
-
-
/**
* Internal function. Adds a child node named \<flag\> to an xmlNode containing a flag value
*
@@ -123,7 +66,7 @@ xmlDoc *eDBadminGetUserList(eurephiaCTX *ctx, const char *sortkeys) {
*
* @return Returns the \c flagged value
*/
-inline int xml_set_flag(xmlNode *node, char *flagname, int flagged) {
+static inline int xml_set_flag(xmlNode *node, char *flagname, int flagged) {
if( flagged ) {
xmlNewChild(node, NULL, (xmlChar *) "flag", (xmlChar *) flagname);
}
@@ -132,19 +75,27 @@ inline int xml_set_flag(xmlNode *node, char *flagname, int flagged) {
/**
- * @copydoc eDBadminGetUserInfo()
+ * Internal function. Retrieves information about user accounts
+ *
+ * @param ctx eurephiaCTX
+ * @param infoType Flags defining which information to be included in the result
+ * @param uinfo_map eDBfieldMap containing information needed for the new user account
+ * @param sortkeys String containing list of fields defining data sorting
+ *
+ * @return Returns an eurephia ResultMsg XML document with status of the operation. On fatal errors,
+ * NULL is returned.
*/
-xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
+static xmlDoc *useracc_view(eurephiaCTX *ctx, unsigned int infoType,
+ eDBfieldMap *uinfo_map, const char *sortkeys)
+{
dbresult *uinf = NULL, *qres = NULL;
- eDBfieldMap *uinfo_map = NULL;
- int flag = 0, uid = 0;
+ unsigned int flag = 0, uid = 0, recid = 0;
char *username = NULL;
-
xmlDoc *doc = NULL;
- xmlNode *root_n = NULL, *info_n = NULL, *fieldmap = NULL;
+ xmlNode *root_n = NULL, *info_n = NULL;
DEBUG(ctx, 20, "Function call: eDBadminGetUserUserInfo(ctx, %i, {xmlDoc})", infoType);
- assert( (ctx != NULL) && (srch != NULL) );
+ assert( ctx != NULL );
if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
eurephia_log(ctx, LOG_CRITICAL, 0,
@@ -152,65 +103,63 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
return NULL;
}
- fieldmap = eurephiaXML_getRoot(ctx, srch, "fieldMapping", 1);
- uinfo_map = eDBxmlMapping(ctx, tbl_sqlite_users, "u", fieldmap);
-
// Query the database, find the user defined in the user map
uinf = sqlite_query_mapped(ctx, SQL_SELECT,
- "SELECT u.username, u.activated, u.deactivated, u.last_accessed, u.uid,"
+ "SELECT users.username, users.activated, users.deactivated,"
+ " users.last_accessed, users.uid,"
" (bl.username IS NOT NULL), opensess, logincount,"
" (at.attempts > 0)"
- " FROM openvpn_users u"
+ " FROM openvpn_users users"
" LEFT JOIN openvpn_blacklist bl USING(username)"
- " LEFT JOIN openvpn_attempts at ON(at.username = u.username)"
+ " LEFT JOIN openvpn_attempts at ON(at.username = users.username)"
" LEFT JOIN (SELECT uid, count(*) AS logincount "
" FROM openvpn_lastlog"
" GROUP BY uid) lc"
- " ON (lc.uid = u.uid)"
+ " ON (lc.uid = users.uid)"
" LEFT JOIN (SELECT uid, count(*) > 0 AS opensess"
" FROM openvpn_lastlog"
" WHERE sessionstatus = 2"
" GROUP BY uid) os"
- " ON (os.uid = u.uid)",
- NULL, uinfo_map, NULL);
+ " ON (os.uid = users.uid)",
+ NULL, uinfo_map, sortkeys);
if( uinf == NULL ) {
eurephia_log(ctx, LOG_ERROR, 0, "Error querying the database for a user");
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Failed to query the user database");
}
- eDBfreeMapping(uinfo_map);
- switch( sqlite_get_numtuples(uinf) ) {
- case 0:
- sqlite_free_results(uinf);
- return 0; // No user found
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &doc, &root_n);
+ xmlNewProp(root_n, (xmlChar *) "mode", (xmlChar *) "view");
+
+ for( recid = 0; recid < sqlite_get_numtuples(uinf); recid++ ) {
+ xmlNode *user_n = xmlNewChild(root_n, NULL, (xmlChar *) "Account", NULL);
+ assert( user_n != NULL );
- case 1:
- uid = atoi_nullsafe(sqlite_get_value(uinf, 0, 4));
- username = sqlite_get_value(uinf, 0, 0);
+ sqlite_xml_value(user_n, XML_ATTR, "uid", uinf, recid, 4);
+ sqlite_xml_value(user_n, XML_NODE, "username", uinf, recid, 0);
- eurephiaXML_CreateDoc(ctx, 1, "user", &doc, &root_n);
- sqlite_xml_value(root_n, XML_NODE, "username", uinf, 0, 0);
- sqlite_xml_value(root_n, XML_ATTR, "uid", uinf, 0, 4);
+ uid = atoi_nullsafe(sqlite_get_value(uinf, recid, 4));
+ username = sqlite_get_value(uinf, recid, 0);
- if( (infoType & USERINFO_user) == USERINFO_user ) {
- info_n = xmlNewChild(root_n, NULL, (xmlChar *) "flags", NULL);
+ if( infoType & USERINFO_user ) {
+ info_n = xmlNewChild(user_n, NULL, (xmlChar *) "flags", NULL);
+ assert( info_n != NULL );
// set DEACTIVATED flag, if deactivated field is not NULL
- xml_set_flag(info_n, "DEACTIVATED", (sqlite_get_value(uinf, 0, 2) != NULL));
+ xml_set_flag(info_n, "DEACTIVATED", (sqlite_get_value(uinf, recid, 2) != NULL));
// set BLACKLISTED flag, if username is found in blacklist table
- xml_set_flag(info_n, "BLACKLISTED", (atoi_nullsafe(sqlite_get_value(uinf, 0, 5))==1));
+ xml_set_flag(info_n, "BLACKLISTED", (atoi_nullsafe(sqlite_get_value(uinf, recid, 5))==1));
// set OPENSESSION flag, if user has a lastlog entry with sessionstatus == 2
- xml_set_flag(info_n, "OPENSESSION", (atoi_nullsafe(sqlite_get_value(uinf, 0, 6))==1));
+ xml_set_flag(info_n, "OPENSESSION", (atoi_nullsafe(sqlite_get_value(uinf, recid, 6))==1));
// set ERRATTEMPT flag, if user has an entry in attempts log with attemtps > 0
- xml_set_flag(info_n, "ERRATTEMPT", (atoi_nullsafe(sqlite_get_value(uinf, 0, 8))==1));
+ xml_set_flag(info_n, "ERRATTEMPT", (atoi_nullsafe(sqlite_get_value(uinf, recid, 8))==1));
// set NEVERUSED flag, if login count == 0 and last_accessed == NULL
flag = xml_set_flag(info_n, "NEVERUSED", ((atoi_nullsafe(sqlite_get_value(uinf,0, 7))==0)
- && (sqlite_get_value(uinf, 0, 3) == NULL)));
+ && (sqlite_get_value(uinf, recid, 3) == NULL)));
// set RSETLASTUSED flag, if login count == 0 and last_accessed == NULL
xml_set_flag(info_n, "RSETLASTUSED", !flag && (sqlite_get_value(uinf,0,3)) == NULL);
@@ -219,13 +168,13 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
xml_set_flag(info_n, "RSETLOGINCNT", ((atoi_nullsafe(sqlite_get_value(uinf,0, 7))==0)
&& (sqlite_get_value(uinf,0,3)) != NULL));
- sqlite_xml_value(root_n, XML_NODE, "activated", uinf, 0, 1);
- sqlite_xml_value(root_n, XML_NODE, "deactivated", uinf, 0, 2);
- info_n = sqlite_xml_value(root_n, XML_NODE, "last_accessed", uinf, 0, 3);
- sqlite_xml_value(info_n, XML_ATTR, "logincount", uinf, 0, 7);
+ sqlite_xml_value(user_n, XML_NODE, "activated", uinf, recid, 1);
+ sqlite_xml_value(user_n, XML_NODE, "deactivated", uinf, recid, 2);
+ info_n = sqlite_xml_value(user_n, XML_NODE, "last_accessed", uinf, recid, 3);
+ sqlite_xml_value(user_n, XML_ATTR, "logincount", uinf, recid, 7);
}
- if( (infoType & USERINFO_certs) == USERINFO_certs ) {
+ if( infoType & USERINFO_certs ) {
// Extract certificate info
qres = sqlite_query(ctx,
"SELECT depth, digest, common_name, organisation, email, "
@@ -237,7 +186,8 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
" ON (uc.accessprofile = a.accessprofile)"
" WHERE uid = '%i' ORDER BY c.certid DESC", uid);
- info_n = xmlNewChild(root_n, NULL, (xmlChar *) "certificates", NULL);
+ info_n = xmlNewChild(user_n, NULL, (xmlChar *) "certificates", NULL);
+ assert( info_n != NULL );
if( (qres != NULL) && (sqlite_get_numtuples(qres) > 0) ) {
int i;
xmlNode *cert, *acpr;
@@ -245,6 +195,7 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
for( i = 0; i < sqlite_get_numtuples(qres); i++ ) {
cert = xmlNewChild(info_n, NULL, (xmlChar *) "certificate", NULL);
+ assert( cert != NULL );
sqlite_xml_value(cert, XML_ATTR, "certid", qres, 0, 6);
sqlite_xml_value(cert, XML_ATTR, "depth", qres, 0, 0);
@@ -266,19 +217,16 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
sqlite_xml_value(acpr, XML_ATTR, "fwdestination", qres, 0, 9);
}
}
-
- if( qres != NULL ) {
- sqlite_free_results(qres);
- }
+ sqlite_free_results(qres);
}
- if( (infoType & USERINFO_lastlog) == USERINFO_lastlog ) {
+ if( infoType & USERINFO_lastlog ) {
int i = 0;
xmlNode *lastl = NULL, *sess = NULL, *tmp1 = NULL, *tmp2 = NULL;
xmlChar *tmp = NULL;
qres = sqlite_query(ctx,
- "SELECT llid, ll.certid, protocol, remotehost, remoteport, macaddr,"
+ "SELECT llid, ll.certid,protocol,remotehost,remoteport,macaddr,"
" vpnipaddr, vpnipmask, sessionstatus, sessionkey,"
" login, logout, session_duration, session_deleted,"
" bytes_sent, bytes_received, uicid, accessprofile,"
@@ -287,19 +235,22 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
" FROM openvpn_lastlog ll"
" LEFT JOIN openvpn_usercerts USING (uid, certid)"
" LEFT JOIN openvpn_accesses USING (accessprofile)"
- " LEFT JOIN openvpn_certificates cert ON (ll.certid = cert.certid)"
+ " LEFT JOIN openvpn_certificates cert ON(ll.certid=cert.certid)"
" WHERE uid = '%i' ORDER BY login, logout", uid);
if( qres == NULL ) {
eurephia_log(ctx, LOG_ERROR, 0, "Quering the lastlog failed");
xmlFreeDoc(doc);
- return NULL;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to query the lastlog");
}
- lastl = xmlNewChild(root_n, NULL, (xmlChar *) "lastlog", NULL);
+ lastl = xmlNewChild(user_n, NULL, (xmlChar *) "lastlog", NULL);
for( i = 0; i < sqlite_get_numtuples(qres); i++ ) {
sess = xmlNewChild(lastl, NULL, (xmlChar*) "session", NULL);
+ assert( sess != NULL );
+
sqlite_xml_value(sess, XML_ATTR, "llid", qres, i, 0);
xmlNewProp(sess, (xmlChar *) "session_status",
(xmlChar *)SESSION_STATUS[atoi_nullsafe(sqlite_get_value(qres, i, 8))]);
@@ -310,6 +261,7 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
sqlite_xml_value(sess, XML_NODE, "session_closed", qres, i, 13);
tmp1 = xmlNewChild(sess, NULL, (xmlChar *) "connection", NULL);
+ assert( tmp1 != NULL );
sqlite_xml_value(tmp1, XML_ATTR, "bytes_sent", qres, i, 14);
sqlite_xml_value(tmp1, XML_ATTR, "bytes_received", qres, i, 15);
sqlite_xml_value(tmp1, XML_NODE, "protocol", qres, i, 2);
@@ -320,6 +272,7 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
sqlite_xml_value(tmp1, XML_NODE, "vpn_netmask", qres, i, 7);
tmp1 = xmlNewChild(sess, NULL, (xmlChar *) "certificate", NULL);
+ assert( tmp1 != NULL );
sqlite_xml_value(tmp1, XML_ATTR, "certid", qres, i, 1);
sqlite_xml_value(tmp1, XML_ATTR, "uicid", qres, i, 16);
sqlite_xml_value(tmp1, XML_ATTR, "depth", qres, i, 20);
@@ -342,7 +295,7 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
sqlite_free_results(qres);
}
- if( (infoType & USERINFO_attempts) == USERINFO_attempts ) {
+ if( infoType & USERINFO_attempts ) {
xmlNode *atmpt = NULL;
qres = sqlite_query(ctx,
@@ -354,10 +307,13 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
eurephia_log(ctx, LOG_ERROR, 0, "Quering for login attempts failed");
sqlite_free_results(qres);
xmlFreeDoc(doc);
- return NULL;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to query the login attempts log");
}
- atmpt = xmlNewChild(root_n, NULL, (xmlChar *) "attempts", NULL);
+ atmpt = xmlNewChild(user_n, NULL, (xmlChar *) "attempts", NULL);
+ assert( atmpt != NULL );
+
if( sqlite_get_numtuples(qres) == 1 ) {
sqlite_xml_value(atmpt, XML_ATTR, "atpid", qres, 0, 3);
sqlite_xml_value(atmpt, XML_ATTR, "attempts", qres, 0, 0);
@@ -367,7 +323,7 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
sqlite_free_results(qres);
}
- if( (infoType & USERINFO_blacklist) == USERINFO_blacklist ) {
+ if( infoType & USERINFO_blacklist ) {
xmlNode *atmpt = NULL;
qres = sqlite_query(ctx,
@@ -379,10 +335,13 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
eurephia_log(ctx, LOG_ERROR, 0, "Quering blacklist log failed");
sqlite_free_results(qres);
xmlFreeDoc(doc);
- return NULL;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to query the blacklist log");
}
- atmpt = xmlNewChild(root_n, NULL, (xmlChar *) "blacklist", NULL);
+ atmpt = xmlNewChild(user_n, NULL, (xmlChar *) "blacklist", NULL);
+ assert( atmpt != NULL );
+
if( sqlite_get_numtuples(qres) == 1 ) {
sqlite_xml_value(atmpt, XML_ATTR, "blid", qres, 0, 2);
sqlite_xml_value(atmpt, XML_NODE, "blacklisted", qres, 0, 0);
@@ -391,103 +350,92 @@ xmlDoc *eDBadminGetUserInfo(eurephiaCTX *ctx, int infoType, xmlDoc *srch) {
sqlite_free_results(qres);
}
- sqlite_free_results(uinf);
- return doc;
- default:
- sqlite_free_results(uinf);
- eurephia_log(ctx, LOG_ERROR, 0, "Too many user records was found.");
- return NULL;
}
+ sqlite_free_results(uinf);
+ return doc;
}
/**
- * @copydoc eDBadminAddUser()
+ * Internal function. Creates a new user account in the database.
+ *
+ * @param ctx eurephiaCTX
+ * @param usrinf_map eDBfieldMap containing information needed for the new user account
+ *
+ * @return Returns an eurephia ResultMsg XML document with status of the operation. On fatal errors,
+ * NULL is returned.
*/
-int eDBadminAddUser(eurephiaCTX *ctx, xmlDoc *userinfo) {
+static xmlDoc *useracc_add(eurephiaCTX *ctx, eDBfieldMap *usrinf_map) {
+ xmlDoc *res_d = NULL;
dbresult *res = NULL;
- xmlNode *usrinf_n = NULL;
- eDBfieldMap *usrinf_map = NULL;
- int uid = 0;
- DEBUG(ctx, 20, "Function call: eDBadminAddUser(ctx, xmlDoc)");
- assert( (ctx != NULL) && (userinfo != NULL) );
+ DEBUG(ctx, 21, "Function call: useracc_add(ctx, eDBfieldMap)");
+ assert( (ctx != NULL) && (usrinf_map != NULL) );
if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
eurephia_log(ctx, LOG_CRITICAL, 0,
"eurephia admin function call attempted with wrong context type");
- return 0;
- }
-
- // Get the add_user node, and then find the fieldMapping node
- usrinf_n = eurephiaXML_getRoot(ctx, userinfo, "add_user", 1);
- if( usrinf_n == NULL ) {
- eurephia_log(ctx, LOG_ERROR, 0, "Could not find proper add user XML document");
- return 0;
- }
- usrinf_n = xmlFindNode(usrinf_n, "fieldMapping");
- if( usrinf_n == NULL ) {
- eurephia_log(ctx, LOG_ERROR, 0, "Could not find proper add user XML document");
- return 0;
+ return NULL;
}
- // Get a proper field mapping to be used by the database
- usrinf_map = eDBxmlMapping(ctx, tbl_sqlite_users, NULL, usrinf_n);
- assert( usrinf_map != NULL );
-
// Register the user
res = sqlite_query_mapped(ctx, SQL_INSERT, "INSERT INTO openvpn_users", usrinf_map, NULL, NULL);
- if( res == NULL ) {
+ if( (res == NULL) || (sqlite_get_affected_rows(res) == 0) ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not register the new user account");
- uid = -1;
+ res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to register the user account");
} else {
- uid = res->last_insert_id;
+ xmlChar *uid = malloc_nullsafe(ctx, 34);
+ xmlNode *info_n = NULL;
+ assert( uid != NULL );
+
+ // Prepare an information tag/node with the new uid value
+ xmlStrPrintf(uid, 32, (xmlChar *) "%ld", res->last_insert_id);
+ info_n = xmlNewNode(NULL, (xmlChar *)"UserAccount");
+ xmlNewProp(info_n, (xmlChar *) "mode", (xmlChar *) "add");
+ xmlNewProp(info_n, (xmlChar *) "uid", uid);
+
+ eurephia_log(ctx, LOG_INFO, 1, "New user account created (uid %i)", res->last_insert_id);
+ res_d = eurephiaXML_ResultMsg(ctx, exmlRESULT, info_n,
+ "New user account created with uid %i", res->last_insert_id);
+ free_nullsafe(ctx, uid);
+ xmlFreeNode(info_n);
}
sqlite_free_results(res);
- eDBfreeMapping(usrinf_map);
- return uid;
+ return res_d;
}
/**
- * @copydoc eDBadminUpdateUser()
- */
-int eDBadminUpdateUser(eurephiaCTX *ctx, const int uid, xmlDoc *userinfo) {
+ * Internal function. Updates a user account
+ *
+ * @param ctx eurephiaCTX
+ * @param uid Numeric user id to be updated
+ * @param value_map eDBfieldMap containing new values
+ *
+ * @return Returns an eurephia ResultMsg XML document with status of the operation. On fatal errors,
+ * NULL is returned.
+*/
+static xmlDoc *useracc_update(eurephiaCTX *ctx, const int uid, eDBfieldMap *value_map) {
dbresult *uinf = NULL;
- xmlDoc *srch_xml = NULL;
- xmlNode *root_n = NULL, *srch_n = NULL, *values_n = NULL;
- eDBfieldMap *value_map = NULL, *srch_map = NULL;
- xmlChar *xmluid = 0;
+ xmlDoc *res_d = NULL, *srch_xml = NULL;
+ xmlNode *srch_n = NULL;
+ xmlChar *xmluid = NULL;
+ eDBfieldMap *srch_map = NULL;
- DEBUG(ctx, 20, "Function call: eDBadminUpdateUser(ctx, %i, xmlDoc)", uid);
- assert( (ctx != NULL) && (userinfo != NULL) );
+ DEBUG(ctx, 21, "Function call: useracc_update(ctx, %i, eDBfieldMap)", uid);
+ assert( (ctx != NULL) && (value_map != NULL) );
if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
eurephia_log(ctx, LOG_CRITICAL, 0,
"eurephia admin function call attempted with wrong context type");
- return 0;
- }
-
- // Get the update_user node
- root_n = eurephiaXML_getRoot(ctx, userinfo, "update_user", 1);
- if( root_n == NULL ) {
- eurephia_log(ctx, LOG_ERROR, 0, "Could not find proper XML element for user update");
- return 0;
- }
-
- // Double check that we are going to update the right user
- xmluid = (xmlChar *)xmlGetAttrValue(root_n->properties, "uid");
- if( atoi_nullsafe((char *)xmluid) != uid ) {
- eurephia_log(ctx, LOG_ERROR, 0, "Mismatch between uid given as parameter and uid in XML");
- return 0;
+ return NULL;
}
- // Grab the fieldMapping node and create a eDBfieldMap structure for it
- values_n = xmlFindNode(root_n, "fieldMapping");
- value_map = eDBxmlMapping(ctx, tbl_sqlite_users, NULL, values_n);
-
- // Create an eDBfieldMap structure for the srch_map (used for WHERE clause)
+ // Create an eDBfieldMap structure for the srch_map (to be used in the WHERE clause)
+ xmluid = (xmlChar *) malloc_nullsafe(ctx, 34);
+ xmlStrPrintf(xmluid, 32, (xmlChar *) "%ld", uid);
eurephiaXML_CreateDoc(ctx, 1, "fieldMapping", &srch_xml, &srch_n);
xmlNewProp(srch_n, (xmlChar *) "table", (xmlChar *) "users");
xmlNewChild(srch_n, NULL, (xmlChar *) "uid", xmluid); // Add uid as the only criteria
@@ -499,59 +447,131 @@ int eDBadminUpdateUser(eurephiaCTX *ctx, const int uid, xmlDoc *userinfo) {
if( uinf == NULL ) {
eurephia_log(ctx, LOG_ERROR, 0, "Error querying the database for a user");
- return 0;
+ eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Failed to update user (uid %i)", uid);
+ } else if( sqlite_get_affected_rows(uinf) == 0 ) {
+ res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Could not find any user account with uid %i", uid);
+ } else {
+ res_d = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
+ "User account with uid %i is updated", uid);
}
sqlite_free_results(uinf);
-
eDBfreeMapping(srch_map);
- eDBfreeMapping(value_map);
xmlFreeDoc(srch_xml);
+ free_nullsafe(ctx, xmluid);
- return 1;
+ return res_d;
}
+
/**
- * @copydoc eDBadminDeleteUser()
+ * Internal function. Deletes a user account from the users table
+ *
+ * @param ctx eurephiaCTX
+ * @param uid Numeric user id of user to be deleted.
+ *
+ * @return Returns an eurephia ResultMsg XML document with status of the operation. On fatal errors,
+ * NULL is returned.
*/
-int eDBadminDeleteUser(eurephiaCTX *ctx, const int uid, xmlDoc *userinfo) {
+static xmlDoc *useracc_delete(eurephiaCTX *ctx, const unsigned int uid) {
+ xmlDoc *res_d = NULL;
dbresult *res = NULL;
- xmlNode *usrinf_n = NULL;
- char *uid_str = NULL;
- int rc = 0;
- DEBUG(ctx, 20, "Function call: eDBadminDeleteUser(ctx, %i, xmlDoc)", uid);
- assert( (ctx != NULL) && (userinfo != NULL) );
+ DEBUG(ctx, 21, "Function call: useracc_delete(ctx, %i)", uid);
+ assert( ctx != NULL );
if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
eurephia_log(ctx, LOG_CRITICAL, 0,
"eurephia admin function call attempted with wrong context type");
- return 0;
- }
-
- // Get the delete_user node
- usrinf_n = eurephiaXML_getRoot(ctx, userinfo, "delete_user", 1);
- if( usrinf_n == NULL ) {
- eurephia_log(ctx, LOG_ERROR, 0, "Could not find proper delete user XML document");
- return 0;
- }
-
- // Get the uid from the XML and compare it with the uid in the function argument
- uid_str = xmlGetAttrValue(usrinf_n->properties, "uid");
- if( (uid_str == NULL) || (atoi_nullsafe(uid_str) != uid) ) {
- eurephia_log(ctx, LOG_ERROR, 0, "Could not find proper delete user XML document. (uid mismatch)");
- return 0;
+ return NULL;
}
// Delete the user
res = sqlite_query(ctx, "DELETE FROM openvpn_users WHERE uid = '%i'", uid);
if( res == NULL ) {
- eurephia_log(ctx, LOG_FATAL, 0, "Could not delete the user account");
- rc = 0;
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not delete the user account (uid %i)", uid);
+ res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to delete the user account (uid %i)", uid);
+ } else if( sqlite_get_affected_rows(res) == 0 ) {
+ res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Could not find any user account with uid %i", uid);
} else {
- rc = 1;
+ res_d = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
+ "User account with uid %i is deleted", uid);
}
sqlite_free_results(res);
- return rc;
+ return res_d;
+}
+
+
+/**
+ * @copydoc eDBadminUserAccount()
+ */
+xmlDoc *eDBadminUserAccount(eurephiaCTX *ctx, xmlDoc *qryxml) {
+ xmlDoc *res_d = NULL;
+ xmlNode *qry_n = NULL, *fmap_n = NULL;
+ eDBfieldMap *fmap_m = NULL;
+ char *mode = NULL;
+ int uid;
+
+ DEBUG(ctx, 20, "Function call: eDBadminUserAccount(ctx, xmlDoc)");
+ assert( (ctx != NULL) && (qryxml != NULL) );
+
+ if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "eurephia admin function call attempted with wrong context type");
+ return NULL;
+ }
+
+ qry_n = eurephiaXML_getRoot(ctx, qryxml, "UserAccount", 1);
+ if( qry_n == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Could not find a valid XML for the user account request");
+ return NULL;
+ }
+ mode = xmlGetAttrValue(qry_n->properties, "mode");
+ if( mode == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Invalid user account request (1).");
+ return NULL;
+ }
+
+ fmap_n = xmlFindNode(qry_n, "fieldMapping");
+ if( fmap_n == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Invalid user account request (2).");
+ return NULL;
+ }
+ fmap_m = eDBxmlMapping(ctx, tbl_sqlite_users, "users", fmap_n);
+ assert(fmap_m != NULL);
+
+ // Extract the value of the uid attribute in the UserAccount tag. If not found, set value to -1.
+ uid = atoi_nullsafe(defaultValue(xmlGetAttrValue(qry_n->properties, "uid"), "-1"));
+
+ if( strcmp(mode, "view") == 0 ) {
+ unsigned int flags = atoi_nullsafe(defaultValue(xmlGetNodeContent(qry_n,"extractFlags"),"0"));
+ const char *sortkeys = xmlGetNodeContent(qry_n, "sortkeys");
+ res_d = useracc_view(ctx, flags, fmap_m, eDBmkSortKeyString(fmap_m, sortkeys));
+ } else if( strcmp(mode, "add") == 0 ) {
+ res_d = useracc_add(ctx, fmap_m);
+ } else if( strcmp(mode, "update") == 0 ) {
+ if( uid == -1 ) {
+ res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Can not update user account without an uid value");
+ } else {
+ res_d = useracc_update(ctx, uid, fmap_m);
+ }
+ } else if( strcmp(mode, "delete") == 0 ) {
+ if( uid == -1 ) {
+ res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Can not delete user account without an uid value");
+ } else {
+ res_d = useracc_delete(ctx, uid);
+ }
+ } else {
+ eurephia_log(ctx, LOG_ERROR, 0, "UserAccount - Unknown mode: '%s'", mode);
+ res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Unknown mode '%s'", mode);
+ }
+ eDBfreeMapping(fmap_m);
+
+ return res_d;
}
@@ -608,11 +628,11 @@ xmlDoc *adminacclvl_Get(eurephiaCTX *ctx, eDBfieldMap *fmap) {
tmp_n = sqlite_xml_value(acl_n, XML_NODE, "access", res, i, 3);
sqlite_xml_value(tmp_n, XML_ATTR, "interface", res, i, 2);
}
-
sqlite_free_results(res);
return doc;
}
+
/**
* @copydoc eDBadminAccessLevel()
*/
diff --git a/database/sqlite/administration/usercerts.c b/database/sqlite/administration/usercerts.c
index 4387dcf..8e235c5 100644
--- a/database/sqlite/administration/usercerts.c
+++ b/database/sqlite/administration/usercerts.c
@@ -57,8 +57,6 @@
#define FMAP_USERCERTS
#include "../fieldmapping.h"
-void xmlReplaceChars(xmlChar *str, char s, char r);
-
/**
* Internal function. Queries the database for a list of user-certificate links
@@ -74,7 +72,7 @@ xmlDoc *usercerts_search(eurephiaCTX *ctx, eDBfieldMap *where_m, const char *sor
xmlNode *link_root_n = NULL, *link_n = NULL, *tmp_n = NULL;
dbresult *res = NULL;
xmlChar tmp[2050];
- char *dbsort = NULL;
+ const char *dbsort = NULL;
int i;
DEBUG(ctx, 21, "Function call: usercerts_search(ctx, eDBfieldMap, '%s')", sortkeys);
@@ -87,7 +85,7 @@ xmlDoc *usercerts_search(eurephiaCTX *ctx, eDBfieldMap *where_m, const char *sor
}
if( sortkeys != NULL ) {
- dbsort = eDBmkSortKeyString(tbl_sqlite_usercerts, sortkeys);
+ dbsort = eDBmkSortKeyString(where_m, sortkeys);
}
res = sqlite_query_mapped(ctx, SQL_SELECT,
diff --git a/database/sqlite/sqlite.c b/database/sqlite/sqlite.c
index 71bd04a..6021462 100644
--- a/database/sqlite/sqlite.c
+++ b/database/sqlite/sqlite.c
@@ -262,6 +262,7 @@ dbresult *sqlite_query(eurephiaCTX *ctx, const char *fmt, ... ) {
if( rc != SQLITE_OK ) {
eurephia_log(ctx, LOG_ERROR, 0, "SQL Error: %s", errMsg);
sqlite3_free(sql); sql = NULL;
+ sqlite3_free(errMsg); errMsg = NULL;
free_nullsafe(ctx, dbres);
return NULL;
}
@@ -345,17 +346,6 @@ char *_build_value_string(eDBfieldMap *ptr) {
/**
- * Wrapper macro, which appends a string to a destination string without exceeding the size
- * of the destination buffer.
- *
- * @param dest Pointer to the destination buffer
- * @param src Pointer to the value being concatenated to the destination string.
- * @param size Size of the destination buffer
- */
-#define append_str(dest, src, size) strncat(dest, src, (size - strlen_nullsafe(dest)))
-
-
-/**
* Internal function. Builds up a part of an SQL query, depending on the buildType. The values
* are taken from a pointer to an eDBfieldMap keeping the values
*
@@ -399,7 +389,7 @@ char *_build_sqlpart(int btyp, eDBfieldMap *map) {
// Put the pieces together and append it to the final result
val = _build_value_string(ptr);
- if( ptr->table_alias != NULL ) {
+ if( (btyp == btWHERE) && (ptr->table_alias != NULL) ) {
append_str(buf, ptr->table_alias, 8192);
append_str(buf, ".", 8192);
}
@@ -544,8 +534,9 @@ dbresult *sqlite_query_mapped(eurephiaCTX *ctx, SQLqueryType qType, const char *
void sqlite_dump_result(FILE *dmp, dbresult *res) {
_sqlite_tuples *row = NULL, *field = NULL;
- if( res == NULL ) {
- fprintf(dmp, "(No records found)");
+ if( (res == NULL) || (res->tuples == NULL) ) {
+ fprintf(dmp, "(No records found)\n");
+ return;
}
/*
@@ -651,30 +642,6 @@ xmlNodePtr sqlite_xml_value(xmlNodePtr node, xmlFieldType xmltyp, char *inname,
#endif
-/**
- * Retrieve number of tuples in a given dbresult structure
- *
- * @param res Pointer to a dbresult
- *
- * @return Returns number of rows/number of tuples in the result.
- */
-int sqlite_get_numtuples(dbresult *res) {
- return (res != NULL ? res->num_tuples : 0);
-}
-
-
-/**
- * Retrieve number of affected tuples in current dbresult structure. This is only useful
- * when called on a result from INSERT, UPDATE or DELETE queries.
- *
- * @param res Pointer to a dbresult
- *
- * @return Returns number of rows/tuples affected by the SQL query
- */
-int sqlite_get_affected_rows(dbresult *res) {
- return (res != NULL ? res->affected_rows : 0);
-}
-
#ifdef SQLITE_DEBUG
/*
* Just a simple test program ... to debug this sqlite wrapper
diff --git a/database/sqlite/sqlite.h b/database/sqlite/sqlite.h
index ce482e4..3885e0c 100644
--- a/database/sqlite/sqlite.h
+++ b/database/sqlite/sqlite.h
@@ -126,7 +126,26 @@ char *sqlite_get_value(dbresult *res, int, int);
xmlNodePtr sqlite_xml_value(xmlNodePtr node, xmlFieldType xmltyp, char *name, dbresult *res, int row, int col);
#endif
void sqlite_dump_result(FILE *, dbresult *);
-int sqlite_get_numtuples(dbresult *);
-int sqlite_get_affected_rows(dbresult *);
+
+
+/**
+ * Retrieve number of tuples in a given dbresult structure
+ *
+ * @param dbres Pointer to a dbresult
+ *
+ * @return Returns number of rows/number of tuples in the result.
+ */
+#define sqlite_get_numtuples(dbres) (dbres != NULL ? dbres->num_tuples : 0)
+
+
+/**
+ * Retrieve number of affected tuples in current dbresult structure. This is only useful
+ * when called on a result from INSERT, UPDATE or DELETE queries.
+ *
+ * @param dbres Pointer to a dbresult
+ *
+ * @return Returns number of rows/tuples affected by the SQL query
+ */
+#define sqlite_get_affected_rows(dbres) (dbres != NULL ? dbres->affected_rows : 0)
#endif /* !SQLITE_H_ */
diff --git a/eurephiadm/commands/users.c b/eurephiadm/commands/users.c
index e314dfe..3b84a5d 100644
--- a/eurephiadm/commands/users.c
+++ b/eurephiadm/commands/users.c
@@ -199,8 +199,9 @@ void help_Users() {
* @return returns 0 on success, otherwise 1.
*/
int list_users(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
- xmlDoc *userlist = NULL;
- int i = 0;
+ xmlDoc *qrydoc = NULL, *userlist = NULL;
+ xmlNode *qry_n = NULL, *fmap_n = NULL;
+ int i = 0, rc = 0;
char *sortkeys = NULL;
const char *xsltparams[] = {"view", "'userlist'", NULL};
@@ -229,12 +230,37 @@ int list_users(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
}
}
+ // Create a query document
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &qrydoc, &qry_n);
+ assert( (qrydoc != NULL) && (qry_n != NULL) );
+
+ xmlNewProp(qry_n, (xmlChar *) "mode", (xmlChar *) "view");
+ xmlNewChild(qry_n, NULL, (xmlChar *) "sortkeys", (xmlChar *)sortkeys);
+ xmlNewChild(qry_n, NULL, (xmlChar *) "extractFlags", (xmlChar *) "1");
+
+ fmap_n = xmlNewChild(qry_n, NULL, (xmlChar *) "fieldMapping", NULL);
+ assert( fmap_n != NULL );
+ xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *) "users");
+
// Retrieve the user list - and display it
- userlist = eDBadminGetUserList(ctx, sortkeys);
- xslt_print_xmldoc(stdout, cfg, userlist, "users.xsl", xsltparams);
+ userlist = eDBadminUserAccount(ctx, qrydoc);
+ if( eurephiaXML_IsResultMsg(ctx, userlist) ) {
+ eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, userlist);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ rc = 1;
+ } else {
+ rc = 2;
+ }
+ free_nullsafe(ctx, res);
+ } else {
+ xslt_print_xmldoc(stdout, cfg, userlist, "users.xsl", xsltparams);
+ rc = 0;
+ }
xmlFreeDoc(userlist);
+ xmlFreeDoc(qrydoc);
- return 0;
+ return rc;
}
@@ -253,7 +279,9 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
int i, crit_set = 0, lastlog_verb = 0;
long int show_info = USERINFO_user | USERINFO_certs;
xmlDoc *user_xml = NULL, *srch_xml = NULL;
- xmlNode *srch_root = NULL;
+ xmlNode *srch_root = NULL, *fmap_n = NULL;
+ xmlChar flags[34];
+
#ifdef FIREWALL
const char *xsltparams[] = {"view", NULL, "firewall", "'1'", "view_digest", "'0'", NULL};
#else
@@ -273,10 +301,14 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
- // Create a fieldMapping XML document, used for searching the user database
- eurephiaXML_CreateDoc(ctx, 1, "fieldMapping", &srch_xml, &srch_root);
- xmlNewProp(srch_root, (xmlChar *) "table", (xmlChar *)"users"); // Which table to search in
+ // Create a UserAccount query XML document
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &srch_xml, &srch_root);
+ xmlNewProp(srch_root, (xmlChar*) "mode", (xmlChar *) "view");
+
+ // Setup the fieldMapping - to narrow the search
+ fmap_n = xmlNewChild(srch_root, NULL, (xmlChar *) "fieldMapping", NULL);
+ xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *)"users");
// Argument parsing
crit_set = 0;
@@ -287,7 +319,7 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
fprintf(stderr, "%s: Invalid user id\n", MODULE);
return 1;
}
- xmlNewChild(srch_root, NULL, (xmlChar *)"uid", (xmlChar *) optargs[0]);
+ xmlNewChild(fmap_n, NULL, (xmlChar *)"uid", (xmlChar *) optargs[0]);
crit_set++;
break;
@@ -296,7 +328,7 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
fprintf(stderr, "%s: User name too short\n", MODULE);
return 1;
}
- xmlNewChild(srch_root, NULL, (xmlChar *)"username", (xmlChar *)optargs[0]);
+ xmlNewChild(fmap_n, NULL, (xmlChar *)"username", (xmlChar *)optargs[0]);
crit_set++;
break;
@@ -336,13 +368,32 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
return 1;
}
- // Search and find the user which was requested
- if( (user_xml = eDBadminGetUserInfo(ctx, show_info, srch_xml)) == NULL ) {
+ xmlStrPrintf(flags, 32, (xmlChar *) "%ld%c", show_info, 0);
+ xmlNewChild(srch_root, NULL, (xmlChar *) "extractFlags", flags);
+
+ // Do the query against the database
+ if( (user_xml = eDBadminUserAccount(ctx, srch_xml)) == NULL ) {
+ xmlFreeDoc(srch_xml);
fprintf(stderr, "%s: User not found\n", MODULE);
return 1;
}
xmlFreeDoc(srch_xml);
+ if( eurephiaXML_IsResultMsg(ctx, user_xml) ) {
+ eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, user_xml);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ free_nullsafe(ctx, res);
+ xmlFreeDoc(user_xml);
+ return 1;
+ }
+ free_nullsafe(ctx, res);
+ } else {
+ xmlFreeDoc(user_xml);
+ fprintf(stderr, "%s: Unknown error\n", MODULE);
+ return 2;
+ }
+
if( show_info & USERINFO_user ) {
xsltparams[1] = "'userinfo'";
xslt_print_xmldoc(stdout, cfg, user_xml, "users.xsl", xsltparams);
@@ -363,12 +414,14 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
xsltparams[1] = "'details'";
}
- user_n = eurephiaXML_getRoot(ctx, user_xml, "user", 1);
+ user_n = eurephiaXML_getRoot(ctx, user_xml, "UserAccount", 1);
+ user_n = xmlFindNode(user_n, "Account");
if( user_n == NULL ) {
fprintf(stderr, "Could not retrieve valid data\n");
xmlFreeDoc(user_xml);
return 1;
}
+
printf("** Lastlog entries for %s\n\n", xmlGetNodeContent(user_n, "username"));
xslt_print_xmldoc(stdout, cfg, user_xml, "lastlog.xsl", xsltparams);
@@ -387,8 +440,6 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
}
-
-
/**
* This function handles activation, deactivation and deletion of an account
*
@@ -401,11 +452,12 @@ int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int
* @return returns 0 on success, otherwise 1.
*/
int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
- xmlDoc *user_xml = NULL, *update_xml = NULL, *srch_xml = NULL, *tmp_xml = NULL;
- xmlNode *user_n = NULL, *update_n = NULL, *srch_root = NULL, *tmp_n = NULL;
+ xmlDoc *user_xml = NULL, *update_xml = NULL, *srch_xml = NULL, *tmp_xml = NULL, *res_xml = NULL;
+ xmlNode *user_n = NULL, *update_n = NULL, *srch_root = NULL, *tmp_n = NULL, *fmap_n = NULL;
eurephiaRESULT *res = NULL;
char *uid_str = NULL, *activated = NULL, *deactivated = NULL, *actmode_str = NULL, *newpwd = NULL;
int i, actmode = 0, rc = 0, crit_set = 0;
+ xmlChar flags[34];
e_options activargs[] = {
{"--uid", "-i", 1},
@@ -434,9 +486,16 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
return 1;
}
- // Create a fieldMapping XML document, used for searching the user database
- eurephiaXML_CreateDoc(ctx, 1, "fieldMapping", &srch_xml, &srch_root);
- xmlNewProp(srch_root, (xmlChar *) "table", (xmlChar *)"users"); // Which table to search in
+ // Create a UserAccount query XML document
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &srch_xml, &srch_root);
+ xmlNewProp(srch_root, (xmlChar*) "mode", (xmlChar *) "view");
+
+ // Setup the fieldMapping - to narrow the search
+ fmap_n = xmlNewChild(srch_root, NULL, (xmlChar *) "fieldMapping", NULL);
+ xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *)"users");
+
+ xmlStrPrintf(flags, 32, (xmlChar *) "%ld%c", USERINFO_user, 0);
+ xmlNewChild(srch_root, NULL, (xmlChar *) "extractFlags", flags);
// Argument parsing
crit_set = 0;
@@ -447,7 +506,7 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
fprintf(stderr, "%s: Invalid user id\n", MODULE);
return 1;
}
- xmlNewChild(srch_root, NULL, (xmlChar *)"uid", (xmlChar *) optargs[0]);
+ xmlNewChild(fmap_n, NULL, (xmlChar *)"uid", (xmlChar *) optargs[0]);
crit_set++;
break;
@@ -456,7 +515,7 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
fprintf(stderr, "%s: User name too short\n", MODULE);
return 1;
}
- xmlNewChild(srch_root, NULL, (xmlChar *)"username", (xmlChar *)optargs[0]);
+ xmlNewChild(fmap_n, NULL, (xmlChar *)"username", (xmlChar *)optargs[0]);
crit_set++;
break;
@@ -489,29 +548,40 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
return 1;
}
- // Search and find the user which was requested
- if( (user_xml = eDBadminGetUserInfo(ctx, USERINFO_user, srch_xml)) == NULL ) {
- fprintf(stderr, "%s: User not found\n", MODULE);
+ // Do the query against the database
+ if( (user_xml = eDBadminUserAccount(ctx, srch_xml)) == NULL ) {
xmlFreeDoc(srch_xml);
+ fprintf(stderr, "%s: User not found\n", MODULE);
return 1;
}
xmlFreeDoc(srch_xml);
- // Parse the user information we received
- user_n = eurephiaXML_getRoot(ctx, user_xml, "user", 1);
+ if( eurephiaXML_IsResultMsg(ctx, user_xml) ) {
+ eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, user_xml);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ free_nullsafe(ctx, res);
+ xmlFreeDoc(user_xml);
+ return 1;
+ }
+ free_nullsafe(ctx, res);
+ }
+
+ user_n = eurephiaXML_getRoot(ctx, user_xml, "UserAccount", 1);
+ user_n = xmlFindNode(user_n, "Account");
if( user_n == NULL ) {
- eurephia_log(ctx, LOG_ERROR, 0, "%s: Could not find user node in the XML document", MODULE);
xmlFreeDoc(user_xml);
+ fprintf(stderr, "%s: No user account information found\n", MODULE);
return 1;
}
-
uid_str = xmlGetAttrValue(user_n->properties, "uid");
activated = defaultValue(xmlGetNodeContent(user_n, "activated"), NULL);
deactivated = defaultValue(xmlGetNodeContent(user_n, "deactivated"), NULL);
// Create a new XML document which will be used to update the user account
- eurephiaXML_CreateDoc(ctx, 1, "update_user", &update_xml, &update_n);
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &update_xml, &update_n);
assert( (update_xml != NULL) && (update_n != NULL) );
+ xmlNewProp(update_n, (xmlChar *) "mode", (xmlChar *) "update");
xmlNewProp(update_n, (xmlChar *) "uid", (xmlChar *) uid_str);
// Add fieldMapping - to correctly map eurephia fields into the database fields
@@ -521,7 +591,7 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
switch( actmode ) {
case 'a': // Activate a user account
if( (activated != NULL) && (deactivated == NULL) ) {
- printf("User account is already active\n");
+ printf("%s: User account is already active\n", MODULE);
goto exit;
} else {
// Set activated field to now()
@@ -534,7 +604,7 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
}
// Do the update of the user account
- rc = eDBadminUpdateUser(ctx, atoi_nullsafe(uid_str), update_xml);
+ res_xml = eDBadminUserAccount(ctx, update_xml);
break;
case 'd': // Deactivate a user account
@@ -552,7 +622,7 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
}
// Do the update of the user account
- rc = eDBadminUpdateUser(ctx, atoi_nullsafe(uid_str), update_xml);
+ res_xml = eDBadminUserAccount(ctx, update_xml);
break;
case 'p': // Change password for a user
@@ -587,7 +657,7 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
// Update with new password
tmp_n = xmlNewChild(update_n, NULL, (xmlChar *) "password", (xmlChar *)newpwd);
xmlNewProp(tmp_n, (xmlChar *) "pwhash", (xmlChar *) "none");
- rc = eDBadminUpdateUser(ctx, atoi_nullsafe(uid_str), update_xml);
+ res_xml = eDBadminUserAccount(ctx, update_xml);
free_nullsafe(ctx, newpwd);
break;
@@ -595,12 +665,27 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
case 'D': // Delete user account
xmlFreeDoc(update_xml); // We need another XML doc to delete users
- eurephiaXML_CreateDoc(ctx, 1, "delete_user", &update_xml, &update_n);
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &update_xml, &update_n);
assert( (update_xml != NULL) && (update_n != NULL) );
+ xmlNewProp(update_n, (xmlChar *) "mode", (xmlChar *) "delete");
xmlNewProp(update_n, (xmlChar *) "uid", (xmlChar *) uid_str);
+ update_n = xmlNewChild(update_n, NULL, (xmlChar *) "fieldMapping", NULL);
+ xmlNewProp(update_n, (xmlChar *) "table", (xmlChar *) "users");
- rc = eDBadminDeleteUser(ctx, atoi_nullsafe(uid_str), update_xml);
+ res_xml = eDBadminUserAccount(ctx, update_xml);
+ // Check if this update failed and abort further operations if it did
+ if( eurephiaXML_IsResultMsg(ctx, res_xml) ) {
+ res = eurephiaXML_ParseResultMsg(ctx, res_xml);
+ if( (res == NULL) || (res->resultType == exmlERROR) ) {
+ free_nullsafe(ctx, res);
+ break;
+ }
+ free_nullsafe(ctx, res);
+ } else {
+ // No ResultMsg document was returned, which is also wrong.
+ break;
+ }
// Delete links between certificates associated to this user account
xmlFreeDoc(update_xml);
eurephiaXML_CreateDoc(ctx, 1, "usercerts", &update_xml, &update_n);
@@ -612,31 +697,36 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
xmlNewChild(update_n, NULL, (xmlChar *) "uid", (xmlChar *) uid_str);
tmp_xml = eDBadminUserCertsLink(ctx, update_xml);
- if( tmp_xml == NULL ) {
- fprintf(stderr, "%s: Failed to remove the user-certs link\n", MODULE);
- }
-
res = eurephiaXML_ParseResultMsg(ctx, tmp_xml);
if( res == NULL ) {
fprintf(stderr, "%s: Failed to remove user <-> certificate link. "
"No results received\n", MODULE);
rc = 0;
+ } else if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
} else {
- if( res->resultType == exmlERROR ) {
- fprintf(stderr, "%s: %s\n", MODULE, res->message);
- };
+ fprintf(stdout, "%s: %s\n", MODULE, res->message);
rc = 1;
- free_nullsafe(ctx, res);
}
+ free_nullsafe(ctx, res);
xmlFreeDoc(tmp_xml);
break;
}
- if( rc == 1 ) {
- printf("%s: User account is %s\n", MODULE, actmode_str);
+ if( eurephiaXML_IsResultMsg(ctx, res_xml) ) {
+ eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, res_xml);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ rc = 0;
+ } else {
+ fprintf(stdout, "%s: %s\n", MODULE, res->message);
+ rc = 1;
+ }
+ free_nullsafe(ctx, res);
} else {
- fprintf(stderr, "%s: Operation failed\n", MODULE);
+ fprintf(stderr, "%s: Unknown error\n", MODULE);
}
+ xmlFreeDoc(res_xml);
exit:
xmlFreeDoc(user_xml);
@@ -657,8 +747,9 @@ int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *
* @return returns 0 on success, otherwise 1.
*/
int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
- xmlDoc *user_xml = NULL;
+ xmlDoc *user_xml = NULL, *resxml = NULL;
xmlNode *node = NULL, *node2 = NULL;
+ eurephiaRESULT *res = NULL;
struct stat cert_stat;
int i = 0, certid = 0, uid = 0, certfile_format = CERTFILE_PEM;
char *uname = NULL, *passwd = NULL, *certfile = NULL, *digest = NULL;
@@ -783,9 +874,10 @@ int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int a
free_nullsafe(ctx, chkpwd);
}
-
// Prepare add user XML document with fieldMapping
- eurephiaXML_CreateDoc(ctx, 1, "add_user", &user_xml, &node);
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &user_xml, &node);
+ xmlNewProp(node, (xmlChar *) "mode", (xmlChar *) "add");
+
node = xmlNewChild(node, NULL, (xmlChar *) "fieldMapping", NULL);
xmlNewProp(node, (xmlChar *) "table", (xmlChar *) "users");
@@ -794,15 +886,38 @@ int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int a
xmlNewProp(node2, (xmlChar *) "pwhash", (xmlChar *) "none");
// Add the user
- uid = eDBadminAddUser(ctx, user_xml);
- if( uid > 0 ) {
- fprintf(stdout, "%s: User registered successfully (user id %i)\n", MODULE, uid);
- } else {
- fprintf(stderr, "%s: Failed to register user\n", MODULE);
- }
+ resxml = eDBadminUserAccount(ctx, user_xml);
+ xmlFreeDoc(user_xml);
memset(passwd, 0, strlen_nullsafe(passwd));
free_nullsafe(ctx, passwd);
- xmlFreeDoc(user_xml);
+ if( (resxml == NULL) || !eurephiaXML_IsResultMsg(ctx, resxml) ) {
+ fprintf(stderr, "%s: Failed to register the user. Unknown failure.\n", MODULE);
+ return 1;
+ }
+
+ res = eurephiaXML_ParseResultMsg(ctx, resxml);
+ if( res == NULL ) {
+ fprintf(stderr, "%s: Failed to register the user. No results returned.\n", MODULE);
+ xmlFreeDoc(resxml);
+ return 1;
+ } else if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
+ return 1;
+ }
+
+ if( xmlStrcmp(res->details->children->name, (xmlChar *) "UserAccount") != 0 ) {
+ fprintf(stderr, "%s: Invalid result value. User account might be registered\n", MODULE);
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
+ return 1;
+ }
+
+ fprintf(stdout, "%s: %s\n", MODULE, res->message);
+ uid = atoi_nullsafe(xmlGetAttrValue(res->details->properties, "uid"));
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
if( (digest != NULL) || (certfile != NULL) ) {
if( digest != NULL ) {
diff --git a/eurephiadm/eurephiadm.c b/eurephiadm/eurephiadm.c
index 21d39e2..1429f24 100644
--- a/eurephiadm/eurephiadm.c
+++ b/eurephiadm/eurephiadm.c
@@ -35,10 +35,13 @@
#include <assert.h>
#include <libgen.h>
+#include <libxml/tree.h>
+
#include <eurephia_nullsafe.h>
#include <eurephia_context.h>
#include <eurephia_log.h>
#include <eurephia_values.h>
+#include <eurephia_xml.h>
#include <eurephiadb_driver.h>
#include <eurephiadb_session_common.h>
#include <eurephiadb.h>
@@ -153,10 +156,34 @@ int cmd_Help(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int a
* @return returns 0 on success, otherwise 1.
*/
int cmd_Logout(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
+ xmlDoc *logoutxml = NULL, *resxml = NULL;
+ xmlNode *logout_n = NULL;
+ eurephiaRESULT *res = NULL;
int rc = 0;
- rc = eDBadminLogout(ctx, argv[0]);
- fprintf(stdout, "%s\n", (rc == 1 ? "Logged out successfully" : "Logout failed."));
- return (rc == 0);
+
+ eurephiaXML_CreateDoc(ctx, 1, "Register", &logoutxml, &logout_n);
+ assert( (logoutxml != NULL) && (logout_n != NULL) );
+ xmlNewProp(logout_n, (xmlChar *) "mode", (xmlChar *) "logout");
+ xmlAddChild(logout_n, xmlNewText((xmlChar *) argv[0])); // A dirty hack, but the sesskey is here
+
+ resxml = eDBadminAuthenticate(ctx, logoutxml);
+ xmlFreeDoc(logoutxml);
+ if( !eurephiaXML_IsResultMsg(ctx, resxml) ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Failed to logout session");
+ rc = 1;
+ } else {
+ res = eurephiaXML_ParseResultMsg(ctx, resxml);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ rc = 1;
+ } else {
+ fprintf(stdout, "%s: %s\n", MODULE, res->message);
+ rc = 0;
+ }
+ }
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
+ return rc;
}
@@ -248,10 +275,12 @@ int eurephia_ConnectDB(eurephiaCTX *ctx, const char *argstr) {
*
* @return Returns a eurephiaSESSION pointer to the authenticated user session on success, otherwise NULL.
*/
-eurephiaSESSION *do_login(eurephiaCTX *ctx, eurephiaVALUES *cfg, const char *req_access) {
+static eurephiaSESSION *do_login(eurephiaCTX *ctx, eurephiaVALUES *cfg, const char *req_access) {
+ xmlDoc *loginxml = NULL, *resxml = NULL;
+ xmlNode *login_n = NULL;
+ eurephiaRESULT *res = NULL;
eurephiaSESSION *session = NULL;
char username[33], password[33], *tmp = NULL;
- int uid = 0;
memset(&username, 0, 33);
memset(&password, 0, 33);
@@ -263,17 +292,36 @@ eurephiaSESSION *do_login(eurephiaCTX *ctx, eurephiaVALUES *cfg, const char *req
}
get_console_input(password, 32, "Password:", 1);
- if( (uid = eDBadminAuth(ctx, req_access, username, password)) < 1 ) {
- // Register failure
- memset(username, 0, 33);
- memset(password, 0, 33);
- return NULL;
- }
+ eurephiaXML_CreateDoc(ctx, 1, "Authenticate", &loginxml, &login_n);
+ assert( (loginxml != NULL) && (login_n != NULL) );
+ xmlNewProp(login_n, (xmlChar *) "mode", (xmlChar *) "user");
+
+ xmlNewChild(login_n, NULL, (xmlChar *) "username", (xmlChar *) username);
+ xmlNewChild(login_n, NULL, (xmlChar *) "password", (xmlChar *) password);
+ xmlNewChild(login_n, NULL, (xmlChar *) "accesslevel", (xmlChar *) req_access);
+ resxml = eDBadminAuthenticate(ctx, loginxml);
+ xmlFreeDoc(loginxml);
memset(username, 0, 33);
memset(password, 0, 33);
+ if( !eurephiaXML_IsResultMsg(ctx, resxml) ) {
+ return NULL;
+ }
+
+ res = eurephiaXML_ParseResultMsg(ctx, resxml);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ free_nullsafe(ctx, res);
+ xmlFreeDoc(resxml);
+ return NULL;
+ }
session = create_session(ctx, NULL);
- snprintf(username, 30, "%i", uid); // Borrow username for converting uid to a string
+ login_n = xmlFindNode(res->details, "UserAccount");
+
+ // Borrow username for converting uid to a string
+ snprintf(username, 30, "%s", xmlGetAttrValue(login_n->properties, "uid"));
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
if( !eDBset_session_value(ctx, session, "uid", username) ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not update session variables (uid)");
@@ -281,17 +329,82 @@ eurephiaSESSION *do_login(eurephiaCTX *ctx, eurephiaVALUES *cfg, const char *req
return NULL;
};
- if( !eDBadminRegisterLogin(ctx, session) ) {
+
+ // Register the session as logged in
+ eurephiaXML_CreateDoc(ctx, 1, "Register", &loginxml, &login_n);
+ assert( (loginxml != NULL) && (login_n != NULL) );
+ xmlNewProp(login_n, (xmlChar *) "mode", (xmlChar *) "login");
+ xmlNewProp(login_n, (xmlChar *) "uid", (xmlChar *) username);
+ xmlAddChild(login_n, xmlNewText((xmlChar *) session->sessionkey));
+
+ resxml = eDBadminAuthenticate(ctx, loginxml);
+ xmlFreeDoc(loginxml);
+ if( !eurephiaXML_IsResultMsg(ctx, resxml) ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not register login");
eDBfree_session(ctx, session);
+ xmlFreeDoc(resxml);
+ return NULL;
+ }
+
+ res = eurephiaXML_ParseResultMsg(ctx, resxml);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ free_nullsafe(ctx, res);
+ xmlFreeDoc(resxml);
+ eDBfree_session(ctx, session);
return NULL;
}
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
return session;
}
/**
+ * Validates an exisiting session key against a requested access level
+ *
+ * @param ctx eurephiaCTX
+ * @param sesskey String containing the session key
+ * @param accesslvl String containing the requested access level
+ *
+ * @return Returns 1 if session is valid and access level is granted to the session, otherwise 0
+ */
+static int validate_session(eurephiaCTX *ctx, const char *sesskey, const char *accesslvl) {
+ xmlDoc *sessxml = NULL, *resxml = NULL;
+ xmlNode *sess_n = NULL;
+ int ret = 0;
+
+ eurephiaXML_CreateDoc(ctx, 1, "Authenticate", &sessxml, &sess_n);
+ assert( (sessxml != NULL) && (sess_n != NULL) );
+ xmlNewProp(sess_n, (xmlChar *) "mode", (xmlChar *) "session");
+
+ xmlNewChild(sess_n, NULL, (xmlChar *) "sessionkey", (xmlChar *) sesskey);
+ xmlNewChild(sess_n, NULL, (xmlChar *) "accesslevel", (xmlChar *) accesslvl);
+
+ resxml = eDBadminAuthenticate(ctx, sessxml);
+ xmlFreeDoc(sessxml);
+ if( !eurephiaXML_IsResultMsg(ctx, resxml) ) {
+ ret = 0;
+ } else {
+ eurephiaRESULT *res = NULL;
+
+ res = eurephiaXML_ParseResultMsg(ctx, resxml);
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+ free_nullsafe(ctx, res);
+ }
+ if( resxml ) {
+ xmlFreeDoc(resxml);
+ }
+ return ret;
+}
+
+/**
* Converts a argument table (char **) into a space separated string (char *)
*
* @param argc argument counter
@@ -454,9 +567,6 @@ int main(int argc, char **argv) {
goto exit;
}
session = do_login(ctx, cfg, call_fnc->accesslvl);
- if( session == NULL ) {
- fprintf(stderr, "Login failed\n");
- }
} else {
// If we are logging out, do so here - without checking the session
if( strcmp(call_fnc->command, "logout") == 0) {
@@ -468,16 +578,13 @@ int main(int argc, char **argv) {
}
// Session file found, check if it still is a valid session
- if( eDBadminValidateSession(ctx, sesskey_file, call_fnc->accesslvl) ) {;
+ if( validate_session(ctx, sesskey_file, call_fnc->accesslvl) ) {;
// If valid, load this session
session = create_session(ctx, sesskey_file);
} else {
// If not valid, remove session file and go to login
remove_session_file(ctx);
session = do_login(ctx, cfg, call_fnc->accesslvl);
- if( session == NULL ) {
- fprintf(stderr, "Login failed\n");
- }
}
}
free_nullsafe(ctx, sesskey_file);
diff --git a/utils/eurephia_init.c b/utils/eurephia_init.c
index 00f6404..06d13b8 100644
--- a/utils/eurephia_init.c
+++ b/utils/eurephia_init.c
@@ -209,7 +209,7 @@ static int config_set(eurephiaCTX *ctx, const char *key, const char *val) {
* @return Returns 1 on success, otherwise 0.
*/
int setup_admin_account(eurephiaCTX *ctx) {
- xmlDoc *xmldoc = NULL;
+ xmlDoc *xmldoc = NULL, *resxml = NULL;
xmlNode *node = NULL, *node2 = NULL;
int uid = 0, i;
char uname[66], pwd1[66], pwd2[66];
@@ -219,20 +219,32 @@ int setup_admin_account(eurephiaCTX *ctx) {
printf("------------------------------------------------------------------------------\n\n");
printf("Checking database for user accounts ... ");
- xmldoc = eDBadminGetUserList(ctx, NULL);
- node = eurephiaXML_getRoot(ctx, xmldoc, "userlist", 1);
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &xmldoc, &node);
+ assert( (xmldoc != NULL) && (node != NULL) );
+ xmlNewProp(node, (xmlChar *) "mode", (xmlChar *) "view");
+
+ node = xmlNewChild(node, NULL, (xmlChar *) "fieldMapping", NULL);
+ assert( node != NULL );
+ xmlNewProp(node, (xmlChar *) "table", (xmlChar *) "users");
+
+ resxml = eDBadminUserAccount(ctx, xmldoc);
+ node = eurephiaXML_getRoot(ctx, resxml, "UserAccount", 1);
if( node == NULL ) {
fprintf(stderr, "Could not retrieve valid data\n");
xmlFreeDoc(xmldoc);
+ xmlFreeDoc(resxml);
return 0;
}
- if( node->children != NULL ) {
+ node = xmlFindNode(node, "Account");
+ if( (node != NULL) ) {
printf("User accounts found, aborting. eurephia is already initialised\n");
xmlFreeDoc(xmldoc);
+ xmlFreeDoc(resxml);
return 0;
}
xmlFreeDoc(xmldoc); xmldoc = NULL;
+ xmlFreeDoc(resxml); resxml = NULL;
printf("None found. Good!\n");
get_console_input(uname, 64, "Admin username: ", 0);
@@ -252,7 +264,8 @@ int setup_admin_account(eurephiaCTX *ctx) {
}
memset(pwd2, 0, 66);
- eurephiaXML_CreateDoc(ctx, 1, "add_user", &xmldoc, &node);
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &xmldoc, &node);
+ xmlNewProp(node, (xmlChar *) "mode", (xmlChar *) "add");
node = xmlNewChild(node, NULL, (xmlChar *) "fieldMapping", NULL);
xmlNewProp(node, (xmlChar *) "table", (xmlChar *) "users");
@@ -261,18 +274,40 @@ int setup_admin_account(eurephiaCTX *ctx) {
xmlNewProp(node2, (xmlChar *) "pwhash", (xmlChar *) "none");
// Add the user
- uid = eDBadminAddUser(ctx, xmldoc);
+ resxml = eDBadminUserAccount(ctx, xmldoc);
memset(pwd1, 0, 66);
+ xmlFreeDoc(xmldoc);
- if( uid > 0 ) {
- fprintf(stdout, "Admin user account registered successfully (user id %i)\n", uid);
- } else {
+ if( !eurephiaXML_IsResultMsg(ctx, resxml) ) {
fprintf(stderr, "Failed to register user\n");
- xmlFreeDoc(xmldoc);
+ if( resxml ) {
+ xmlFreeDoc(resxml);
+ }
return 0;
- }
- xmlFreeDoc(xmldoc);
+ } else {
+ eurephiaRESULT *res = NULL;
+ res = eurephiaXML_ParseResultMsg(ctx, resxml);
+ switch( res->resultType ) {
+ case exmlERROR:
+ fprintf(stderr, "** ERROR ** %s\n", res->message);
+ uid = 0;
+ break;
+
+ case exmlRESULT:
+ fprintf(stdout, "%s\n", res->message);
+ node = xmlFindNode(res->details, "UserAccount");
+ uid = atoi_nullsafe(xmlGetAttrValue(node->properties, "uid"));
+ break;
+ }
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
+
+ if( uid < 1 ) {
+ fprintf(stderr, "Failed to register user\n");
+ return 0;
+ }
+ }
// Grant all available access levels to the admin account
static char *grants[] = { "config", "useradmin", "certadmin", "fwprofiles",
@@ -312,7 +347,8 @@ int setup_admin_account(eurephiaCTX *ctx) {
// Activate the user account
printf("Activating the user account ... ");
- eurephiaXML_CreateDoc(ctx, 1, "update_user", &xmldoc, &node);
+ eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &xmldoc, &node);
+ xmlNewProp(node, (xmlChar *) "mode", (xmlChar *) "update");
xmlNewProp(node, (xmlChar *) "uid", (xmlChar *) uname); // uid should still be in uname as string
// Add fieldMapping - to correctly map eurephia fields into the database fields
@@ -320,11 +356,30 @@ int setup_admin_account(eurephiaCTX *ctx) {
xmlNewProp(node2, (xmlChar *) "table", (xmlChar *) "users");
xmlNewChild(node2, NULL, (xmlChar *) "activated", (xmlChar *) "CURRENT_TIMESTAMP");
- if( !eDBadminUpdateUser(ctx, uid, xmldoc) ) {
+ resxml = eDBadminUserAccount(ctx, xmldoc);
+ if( !eurephiaXML_IsResultMsg(ctx, resxml) ) {
printf("FAILED\n");
xmlFreeDoc(xmldoc);
+ xmlFreeDoc(resxml);
return 0;
+ } else {
+ eurephiaRESULT *res = NULL;
+
+ res = eurephiaXML_ParseResultMsg(ctx, resxml);
+ switch( res->resultType ) {
+ case exmlERROR:
+ fprintf(stderr, "** ERROR ** %s\n", res->message);
+ break;
+
+ case exmlRESULT:
+ break;
+ }
+ xmlFreeDoc(resxml);
+ free_nullsafe(ctx, res);
}
+
+
+
printf("Done");
xmlFreeDoc(xmldoc);
@@ -563,6 +618,7 @@ int main(int argc, char **argv) {
int argi = 0;
eurephiaVALUES *cfg = NULL;
eurephiaCTX *ctx = NULL;
+ int rc = 0;
static e_options argopts[] = {
{"--version", "-V", 0},
@@ -582,10 +638,13 @@ int main(int argc, char **argv) {
switch( eurephia_getopt(&argi, argc, argv, argopts) ) {
case 'V':
print_version(argv[0]);
- return 0;
+ rc = 0;
+ goto exit;
+
case 'h':
print_help(argv[0]);
- return 0;
+ rc = 0;
+ goto exit;
case 'l':
eAdd_value(NULL, cfg, "log", optargs[0]);
@@ -612,56 +671,67 @@ int main(int argc, char **argv) {
break;
default:
- return 1;
+ rc = 1;
+ goto exit;
}
}
if( eGet_value(cfg, "database_driver") == NULL ) {
fprintf(stderr, "Missing required database driver (--database-driver)\n");
- return 2;
+ rc = 2;
+ goto exit;
}
if( eGet_value(cfg, "database_params") == NULL ) {
fprintf(stderr, "Missing required database driver parameters (--database-args)\n");
- return 2;
+ rc = 2;
+ goto exit;
}
ctx = eurephiaCTX_init("eurephia_init", NULL, 0, cfg);
if( ctx == NULL ) {
fprintf(stderr, "Failed to initialise an eurephia context.\n");
- return 3;
+ rc = 3;
+ goto exit;
}
if( !eurephia_ConnectDB(ctx, cfg) ) {
fprintf(stderr, "Failed to access the database.\n");
- return 4;
+ rc = 4;
+ goto exit;
}
if( !setup_password_params(ctx, hash_thr_min, hash_thr_max) ) {
- return 11;
+ rc = 11;
+ goto exit;
}
if( !setup_admin_account(ctx) ) {
- return 12;
+ rc = 12;
+ goto exit;
}
if( !setup_session_params(ctx) ) {
- return 13;
+ rc = 13;
+ goto exit;
}
if( !setup_attempt_limits(ctx) ) {
- return 14;
+ rc = 14;
+ goto exit;
}
#ifdef FW_IPTABLES
if( !setup_iptables(ctx) ){
- return 15;
+ rc = 15;
+ goto exit;
}
#endif
printf("\neurephia is now configured. For further changes, please use the eurephiadm utility.\n\n");
+ exit:
eFree_values(ctx, cfg);
eurephiaCTX_destroy(ctx);
return 0;
diff --git a/xslt/eurephiadm/certificates.xsl b/xslt/eurephiadm/certificates.xsl
index c79dae2..945c939 100644
--- a/xslt/eurephiadm/certificates.xsl
+++ b/xslt/eurephiadm/certificates.xsl
@@ -24,10 +24,10 @@
<xsl:strip-space elements="*"/>
<xsl:template match="/eurephia">
- <xsl:apply-templates select="certificates|user/certificates"/>
+ <xsl:apply-templates select="certificates|UserAccount/Account/certificates"/>
</xsl:template>
- <xsl:template match="/eurephia/certificates|/eurephia/user/certificates">
+ <xsl:template match="/eurephia/certificates|/eurephia/UserAccount/Account/certificates">
<xsl:text> ID (D) Common name Organisation&#10;</xsl:text>
<xsl:text> e-mail Registered&#10;</xsl:text>
<xsl:if test="$view_digest = '1'">
diff --git a/xslt/eurephiadm/lastlog.xsl b/xslt/eurephiadm/lastlog.xsl
index da5ac7c..5484ce3 100644
--- a/xslt/eurephiadm/lastlog.xsl
+++ b/xslt/eurephiadm/lastlog.xsl
@@ -26,10 +26,10 @@
<xsl:template match="/eurephia">
<xsl:choose>
<xsl:when test="$view = 'list'">
- <xsl:apply-templates select="lastlog|user/lastlog" mode="list"/>
+ <xsl:apply-templates select="lastlog|UserAccount/Account/lastlog" mode="list"/>
</xsl:when>
<xsl:when test="$view = 'details' or $view = 'details2'">
- <xsl:apply-templates select="lastlog|user/lastlog" mode="details"/>
+ <xsl:apply-templates select="lastlog|UserAccount/Account/lastlog" mode="details"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">Invalid view: <xsl:value-of select="$view"/></xsl:message>
diff --git a/xslt/eurephiadm/users.xsl b/xslt/eurephiadm/users.xsl
index cae7a66..6ded6f6 100644
--- a/xslt/eurephiadm/users.xsl
+++ b/xslt/eurephiadm/users.xsl
@@ -26,13 +26,13 @@
<xsl:template match="/eurephia">
<xsl:choose>
<xsl:when test="$view = 'userlist'">
- <xsl:apply-templates select="userlist" mode="userlist"/>
+ <xsl:apply-templates select="UserAccount" mode="userlist"/>
</xsl:when>
<xsl:when test="$view = 'userinfo'">
- <xsl:apply-templates select="user" mode="userinfo"/>
+ <xsl:apply-templates select="UserAccount/Account" mode="userinfo"/>
</xsl:when>
<xsl:when test="$view = 'attemptblacklist'">
- <xsl:apply-templates select="user" mode="attemptblacklist"/>
+ <xsl:apply-templates select="UserAccount/Account" mode="attemptblacklist"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">Invalid view: <xsl:value-of select="$view"/></xsl:message>
@@ -40,14 +40,14 @@
</xsl:choose>
</xsl:template>
- <xsl:template match="/eurephia/userlist" mode="userlist">
+ <xsl:template match="/eurephia/UserAccount" mode="userlist">
<xsl:text> ID Username Activated Deactivated Last access&#10;</xsl:text>
<xsl:text> ------------------------------------------------------------------------------&#10;</xsl:text>
- <xsl:apply-templates select="user" mode="userlist"/>
+ <xsl:apply-templates select="Account" mode="userlist"/>
<xsl:text> ------------------------------------------------------------------------------&#10;</xsl:text>
</xsl:template>
- <xsl:template match="/eurephia/userlist/user" mode="userlist">
+ <xsl:template match="/eurephia/UserAccount/Account" mode="userlist">
<xsl:text> </xsl:text>
<xsl:call-template name="left-align">
<xsl:with-param name="value" select="@uid"/>
@@ -98,7 +98,7 @@
<xsl:text>&#10;</xsl:text>
</xsl:template>
- <xsl:template match="/eurephia/user" mode="userinfo">
+ <xsl:template match="/eurephia/UserAccount/Account" mode="userinfo">
<xsl:text> User id: </xsl:text>
<xsl:value-of select="@uid"/>
<xsl:text>&#10;</xsl:text>
@@ -142,7 +142,7 @@
<xsl:text>&#10;</xsl:text>
</xsl:template>
- <xsl:template match="/eurephia/user" mode="attemptblacklist">
+ <xsl:template match="/eurephia/UserAccount/Account" mode="attemptblacklist">
<xsl:text>Login attempt information: </xsl:text>
<xsl:choose>
<xsl:when test="count(attempts/*) > 0">