summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt8
-rw-r--r--device-functions.c94
2 files changed, 89 insertions, 13 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68f91f2..ad641cf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,16 @@
cmake_minimum_required(VERSION 2.8)
project(Instrument)
-
+include(FindPkgConfig)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
find_package(Glib)
find_package(GIO)
find_package(Mhash)
+
+pkg_check_modules(LIBUSER REQUIRED libuser)
+add_definitions(${LIBUSER_CFLAGS})
+link_libraries(${LIBUSER_LDFLAGS})
+link_libraries(-lpam)
+
include_directories(${GLIB_PKG_INCLUDE_DIRS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -funsigned-char -Wall")
add_executable(instr-daemon instr-daemon.c
diff --git a/device-functions.c b/device-functions.c
index f96cfef..30fac09 100644
--- a/device-functions.c
+++ b/device-functions.c
@@ -9,7 +9,10 @@
#include "menus.h"
#include <math.h>
#include <glib.h>
-
+#include <libuser/user.h>
+#include <libuser/config.h>
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
void idn_string(gchar** response)
{
@@ -4566,27 +4569,94 @@ int IO_Setup_RS232(int baud, char hardhand, gboolean update_flash)
return OK;
}
-int change_password (gchar *old_password, gchar *new_password)
-{
+// this is a conversation handler for pam, it basically sends the password when pam asks for it
+
+static int conversation(int num_msg, const struct pam_message **msgs, struct pam_response **resp, void *appdata_ptr) {
+
+ struct pam_response* responses = calloc(num_msg, sizeof(struct pam_response));
+ if (!responses) {
+ return PAM_CONV_ERR;
+ }
+
+ int i; // not compiling in gnu99 mode?
+ for (i = 0; i < num_msg; i++) {
+ const struct pam_message *msg = msgs[i];
+ struct pam_response* response = &(responses[i]);
+ switch (msg->msg_style) {
+ case PAM_PROMPT_ECHO_OFF:
+ response->resp = strdup((char*) appdata_ptr);
+ if (!response->resp)
+ return PAM_CONV_ERR;
+ break;
+
+ default:
+ return PAM_CONV_ERR;
+ }
+ response->resp_retcode = 0;
+ }
+
+ *resp = responses;
+
+ return PAM_SUCCESS;
+}
+
+static gboolean checkpassword(const char* username, char* password) {
+ struct pam_conv pam_conversation = { conversation, password };
+ pam_handle_t* pamh;
+
+ if (pam_start("passwd", username, &pam_conversation, &pamh) != PAM_SUCCESS)
+ return FALSE;
+
+ if (pam_authenticate(pamh, 0) != PAM_SUCCESS)
+ return FALSE;
+
+ // we only want to check the password and not actually start a session, so get out of here
+
+ pam_end(pamh, 0);
+
+ return TRUE;
+}
+
+int change_password(gchar *old_password, gchar *new_password) {
gboolean old_valid = TRUE;
- // user = admin
- // (always)
+ char* user = "admin";
// Skip password check if the supplied old_password is NULL. This
// only happens when resetting the password to the default.
- if (old_password != NULL) {
- printf ("verifying old password: %s\n", old_password); //FIXME with real function
- // check, and set old_valid = FALSE if the password check fails
+ if (old_password != NULL ) {
+ printf("verifying old password: %s\n", old_password); //FIXME with real function
+ old_valid = checkpassword(user,old_password);
}
if (old_valid == TRUE) {
- printf ("setting new password: %s\n" ,new_password); //FIXME with real function
- // is a success test required?
+ printf("setting new password: %s\n", new_password); //FIXME with real function
+ struct lu_context *ctx;
+ struct lu_error *error = NULL;
+ struct lu_ent *ent;
+
+ ctx = lu_start(user, lu_user, NULL, NULL, lu_prompt_console_quiet, NULL, &error);
+
+ if (ctx == NULL ) {
+ return password_change_error;
+ }
+
+ ent = lu_ent_new();
+
+ if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) {
+ return password_change_error; // user doesn't exist
+ }
+
+ if (lu_user_setpass(ctx, ent, new_password, FALSE, &error) == FALSE) {
+ return password_change_error;
+ }
+
+ lu_end(ctx);
+
return OK;
- } else {
+ }
+ else {
return password_change_error;
}
}
-