diff --git a/include/msgapi.h b/include/msgapi.h index 570d572..f6e58a8 100644 --- a/include/msgapi.h +++ b/include/msgapi.h @@ -33,7 +33,8 @@ EXPORT BOOL MsgAuthFindUser(const char *user); EXPORT BOOL MsgAuthVerifyPassword(const char *user, const char *password); -EXPORT BOOL MsgAuthSetPassword(const char *user, const char *oldpassword, const char *newpassword); +EXPORT BOOL MsgAuthChangePassword(const char *user, const char *oldpassword, const char *newpassword); +EXPORT BOOL MsgAuthSetPassword(const char *user, const char *password); EXPORT BOOL MsgAuthGetUserStore(const char *user, struct sockaddr_in *store); EXPORT int MsgAuthInitDB(void); EXPORT BOOL MsgAuthAddUser(const char *user); diff --git a/src/apps/config/config.c b/src/apps/config/config.c index 41468fa..6f05520 100644 --- a/src/apps/config/config.c +++ b/src/apps/config/config.c @@ -33,7 +33,8 @@ usage(void) { " -v, --verbose verbose output\n" " -s, --silent non-interactive mode\n\n" "Commands:\n" - " add-user add a user to the systen\n" + " user add add a user to the systen\n" + " user password set the password of a user\n" " install do the initial Bongo install\n" " crypto regenerate data needed for encryption\n" " checkversion see if a newer Bongo is available\n" @@ -186,8 +187,8 @@ ImportSystemBackupFile(StoreClient *client, const char *path) XplConsolePrintf(" Read error!"); } - delim = strrchr(filename, '/'); - *delim = 0; + delim = strrchr(filename, '/'); + *delim = 0; snprintf(fullpath, 108, "/%s", filename); if (!PutOrReplaceConfig(client, fullpath, delim+1, file, filesize)) { @@ -305,6 +306,9 @@ GetInteractiveData(char *description, char **data, char *def) { MemFree(*data); *data = def; } + + size = strlen(line); + if (line[size-1] == '\n') line[size-1] = 0; } #define CERTSIZE 10240 @@ -486,7 +490,7 @@ CheckVersion() { } void -AddUser(const char *username) { +UserAdd(const char *username) { if (MsgAuthAddUser(username)) { XplConsolePrintf(_("Added user %s\n"), username); } else { @@ -494,6 +498,27 @@ AddUser(const char *username) { } } +void +UserPassword(const char *username) { + char *password = NULL; + char *password2 = NULL; + + GetInteractiveData(_("New password for the user"), &password, ""); + GetInteractiveData(_("Confirm the password"), &password2, ""); + + if (strlen(password) == 0) { + XplConsolePrintf(_("ERROR: Can't set password to empty string.\n")); + return; + } + if (strncmp(password, password2, strlen(password))) { + XplConsolePrintf(_("ERROR: The passwords provided don't match.\n")); + return; + } + + if (MsgAuthSetPassword(username, password) == FALSE) { + XplConsolePrintf(_("ERROR: Couldn't set the password for the user.\n")); + } +} void TzCache() { @@ -547,7 +572,7 @@ main(int argc, char *argv[]) { command = 3; } else if (!strcmp(argv[next_arg], "tzcache")) { command = 4; - } else if (!strcmp(argv[next_arg], "add-user")) { + } else if (!strcmp(argv[next_arg], "user")) { command = 5; } else { printf("Unrecognized command: %s\n", argv[next_arg]); @@ -566,18 +591,13 @@ main(int argc, char *argv[]) { // we don't want to setup libraries unless we need to (e.g., to run an agent) if (command == 1) { - startup = BA_STARTUP_CONNIO; + startup = BA_STARTUP_CONNIO; if (-1 == BongoAgentInit(&configtool, "bongoconfig", "", DEFAULT_CONNECTION_TIMEOUT, startup)) { XplConsolePrintf(_("ERROR : Couldn't initialize Bongo libraries\n")); return 2; } } - // don't give away privileges if we're going to need them later. - if (command != 1) { - RunAsBongoUser(); - } - next_arg++; switch(command) { case 1: @@ -585,20 +605,31 @@ main(int argc, char *argv[]) { InitialStoreConfiguration(); break; case 2: + RunAsBongoUser(); GenerateCryptoData(); break; - case 3: + case 3: + RunAsBongoUser(); CheckVersion(); break; case 4: + RunAsBongoUser(); TzCache(); break; case 5: - if (next_arg >= argc) { - XplConsolePrintf(_("USAGE : add-user \n")); + if ((next_arg + 1) >= argc) { + XplConsolePrintf(_("USAGE : user [add|password] \n")); } else { + char *command = argv[next_arg++]; char *username = argv[next_arg]; - AddUser(username); + + if (! strncmp(command, "add", 3)) { + UserAdd(username); + } else if (!strncmp(command, "password", 8)) { + UserPassword(username); + } else { + XplConsolePrintf(_("ERROR: Unknown command '%s' on user\n"), command); + } } break; default: diff --git a/src/libs/msgapi/msgauth.c b/src/libs/msgapi/msgauth.c index 8a472ba..e1429a9 100644 --- a/src/libs/msgapi/msgauth.c +++ b/src/libs/msgapi/msgauth.c @@ -20,6 +20,7 @@ typedef struct { MsgSQLStatement find_user; MsgSQLStatement auth_user; MsgSQLStatement add_user; + MsgSQLStatement set_password; } MsgAuthStatements; MsgAuthStatements msgauth_stmts; @@ -176,11 +177,12 @@ MsgAuthAddUser(const char *user) handle = MsgSQLOpen(path, NULL, 1000); if (NULL == handle) return FALSE; - stmt = MsgSQLPrepare (handle, "INSERT INTO users (username) VALUES (?);", + stmt = MsgSQLPrepare (handle, + "INSERT INTO users (username) VALUES (?);", &msgauth_stmts.add_user); - - if (MsgSQLBindString(stmt, 1, user, TRUE)) return 0; - if (MsgSQLExecute(handle, stmt)) return 0; + + if (MsgSQLBindString(stmt, 1, user, TRUE)) return FALSE; + if (MsgSQLExecute(handle, stmt)) return FALSE; MsgSQLFinalize(stmt); MsgSQLClose(handle); @@ -189,16 +191,50 @@ MsgAuthAddUser(const char *user) } /** - * Reset the user's password + * Change the user's password from an old one to a new one * \param user User whose password we're resetting * \param oldpassword Their old password * \param newpassword The new password we want to have * \return Whether or not we successfully changed the password */ BOOL -MsgAuthSetPassword(const char *user, const char *oldpassword, const char *newpassword) +MsgAuthChangePassword(const char *user, const char *oldpassword, const char *newpassword) { - return FALSE; + if (! MsgAuthVerifyPassword(user, oldpassword)) return FALSE; + + return MsgAuthSetPassword(user, newpassword); +} + +/** + * Set the user's password. SECURITY: We should make sure we're + * authorised to do this. + * \param user User whose password we're setting. + * \param password New password we want to set + * \return Whether or not the password got changed + */ +BOOL +MsgAuthSetPassword(const char *user, const char *password) +{ + MsgSQLStatement *stmt; + char path[XPL_MAX_PATH + 1]; + MsgSQLHandle *handle; + + MsgAuthDBPath(&path, XPL_MAX_PATH); + handle = MsgSQLOpen(path, NULL, 1000); + if (NULL == handle) return FALSE; + + stmt = MsgSQLPrepare (handle, + "UPDATE users SET password = ? WHERE username= ?;", + &msgauth_stmts.set_password); + + if (MsgSQLBindString(stmt, 1, password, TRUE)) return FALSE; + if (MsgSQLBindString(stmt, 2, user, TRUE)) return FALSE; + if (MsgSQLExecute(handle, stmt)) return FALSE; + + MsgSQLFinalize(stmt); + MsgSQLClose(handle); + + return TRUE; } /** diff --git a/src/libs/msgapi/sqldb.c b/src/libs/msgapi/sqldb.c index 33d42ba..e78708e 100644 --- a/src/libs/msgapi/sqldb.c +++ b/src/libs/msgapi/sqldb.c @@ -229,9 +229,9 @@ MsgSQLPrepare(MsgSQLHandle *handle, const char *statement, MsgSQLStatement *stmt XplDelay(MSGSQL_STMT_SLEEP_MS); continue; default: - // FIXME - //XplConsolePrintf("SQL Prepare statement \"%s\" failed; %s\r\n", - // statement, sqlite3_errmsg(handle->db)); + // FIXME: should be logging here. + XplConsolePrintf("SQL Prepare statement \"%s\" failed; %s\r\n", + statement, sqlite3_errmsg(handle->db)); return NULL; } } @@ -264,7 +264,7 @@ MsgSQLExecute(MsgSQLHandle *handle, MsgSQLStatement *_stmt) if (SQLITE_DONE == result) { return 0; } else { - XplConsolePrintf("Sql: %s\r\n", sqlite3_errmsg(handle->db)); + XplConsolePrintf("Sql (%d): %s\r\n", result, sqlite3_errmsg(handle->db)); return -1; } }