1 #include "otsdaq-core/WebUsersUtilities/WebUsers.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
9 #include <openssl/sha.h>
22 #define WEB_LOGIN_BKUP_DB_PATH "bkup/"
24 #define SECURITY_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/security.dat"
26 #define USERS_ACTIVE_SESSIONS_FILE USERS_DB_PATH + "/activeSessions.sv"
28 #define HASHES_DB_FILE HASHES_DB_PATH + "/hashes.xml"
29 #define USERS_DB_FILE USERS_DB_PATH + "/users.xml"
30 #define USERS_GLOBAL_HISTORY_FILE "__global"
31 #define USERS_LOGIN_HISTORY_FILETYPE "hist"
32 #define USERS_PREFERENCES_FILETYPE "pref"
33 #define SYSTEM_PREFERENCES_PREFIX "system.preset"
34 #define USER_WITH_LOCK_FILE WEB_LOGIN_DB_PATH + "/user_with_lock.dat"
36 #define HASHES_DB_GLOBAL_STRING "hashData"
37 #define HASHES_DB_ENTRY_STRING "hashEntry"
38 #define USERS_DB_GLOBAL_STRING "userData"
39 #define USERS_DB_ENTRY_STRING "userEntry"
40 #define USERS_DB_NEXT_UID_STRING "nextUserId"
43 #define PREF_XML_BGCOLOR_FIELD "pref_bgcolor" // -background color
44 #define PREF_XML_DBCOLOR_FIELD "pref_dbcolor" // -dashboard color
45 #define PREF_XML_WINCOLOR_FIELD "pref_wincolor" // -window color
46 #define PREF_XML_LAYOUT_FIELD "pref_layout" // -3 defaults window layouts(and current)
47 #define PREF_XML_SYSLAYOUT_FIELD "pref_syslayout" // -2 defaults window layouts
48 #define PREF_XML_PERMISSIONS_FIELD "desktop_user_permissions" // 0-255 permissions valud (255 is admin super user)
49 #define PREF_XML_USERLOCK_FIELD "username_with_lock" // user with lock (to lockout others)
50 #define PREF_XML_USERNAME_FIELD "pref_username" // user with lock (to lockout others)
52 #define PREF_XML_BGCOLOR_DEFAULT "rgb(15,34,105)" // -background color
53 #define PREF_XML_DBCOLOR_DEFAULT "rgb(60,64,75)" // -dashboard color
54 #define PREF_XML_WINCOLOR_DEFAULT "rgba(196,229,255,0.9)" // -window color
55 #define PREF_XML_LAYOUT_DEFAULT "0;0;0;0" // 3 default window layouts(and current)
56 #define PREF_XML_SYSLAYOUT_DEFAULT "0;0" // 2 system default window layouts
58 #define PREF_XML_ACCOUNTS_FIELD "users_accounts" // user accounts field for super users
59 #define PREF_XML_LOGIN_HISTORY_FIELD "login_entry" // login history field for user login history data
61 const std::string WebUsers::DEFAULT_ADMIN_USERNAME =
"admin";
62 const std::string WebUsers::DEFAULT_ADMIN_DISPLAY_NAME =
"Administrator";
63 const std::string WebUsers::DEFAULT_ADMIN_EMAIL =
"root@otsdaq.fnal.gov";
64 const std::string WebUsers::DEFAULT_ITERATOR_USERNAME =
"iterator";
66 const std::string WebUsers::REQ_NO_LOGIN_RESPONSE =
"NoLogin";
67 const std::string WebUsers::REQ_NO_PERMISSION_RESPONSE =
"NoPermission";
68 const std::string WebUsers::REQ_USER_LOCKOUT_RESPONSE =
"UserLockout";
70 const std::string WebUsers::SECURITY_TYPE_NONE =
"NoSecurity";
71 const std::string WebUsers::SECURITY_TYPE_DIGEST_ACCESS =
"DigestAccessAuthentication";
74 #define __MF_SUBJECT__ "WebUsers"
82 usersUsernameWithLock_ =
"";
85 HashesDatabaseEntryFields.push_back(
"hash");
86 HashesDatabaseEntryFields.push_back(
"lastAccessTime");
88 UsersDatabaseEntryFields.push_back(
"username");
89 UsersDatabaseEntryFields.push_back(
"displayName");
90 UsersDatabaseEntryFields.push_back(
"salt");
91 UsersDatabaseEntryFields.push_back(
"uid");
92 UsersDatabaseEntryFields.push_back(
"permissions");
93 UsersDatabaseEntryFields.push_back(
"lastLoginAttemptTime");
94 UsersDatabaseEntryFields.push_back(
"accountCreatedTime");
95 UsersDatabaseEntryFields.push_back(
"loginFailureCount");
96 UsersDatabaseEntryFields.push_back(
"lastModifiedTime");
97 UsersDatabaseEntryFields.push_back(
"lastModifierUsername");
98 UsersDatabaseEntryFields.push_back(
"useremail");
101 mkdir(((std::string)WEB_LOGIN_DB_PATH).c_str(), 0755);
102 mkdir(((std::string)WEB_LOGIN_DB_PATH +
"bkup/" + USERS_DB_PATH).c_str(), 0755);
103 mkdir(((std::string)WEB_LOGIN_DB_PATH + HASHES_DB_PATH).c_str(), 0755);
104 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH).c_str(), 0755);
105 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_LOGIN_HISTORY_PATH).c_str(), 0755);
106 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_PREFERENCES_PATH).c_str(), 0755);
109 if (!loadDatabases())
110 __COUT__ <<
"FATAL USER DATABASE ERROR - failed to load!!!" << std::endl;
112 loadSecuritySelection();
117 std::string user = DEFAULT_ADMIN_USERNAME;
118 if ((i = searchUsersDatabaseForUsername(user)) == NOT_FOUND_IN_DATABASE)
120 __SS__ <<
"user: " << user <<
" is not found" << std::endl;
121 __COUT_ERR__ << ss.str();
122 throw std::runtime_error(ss.str());
125 else if (UsersSaltVector[i] ==
"" &&
126 securityType_ == SECURITY_TYPE_DIGEST_ACCESS)
128 char charTimeStr[10];
129 sprintf(charTimeStr,
"%d",
int(UsersAccountCreatedTimeVector[i] & 0xffff));
130 std::string tmpTimeStr = charTimeStr;
135 std::thread([](std::string nac, std::string user) { WebUsers::NACDisplayThread(nac, user); },
136 tmpTimeStr, user).detach();
142 loadActiveSessions();
150 __COUT__ <<
"Done with Web Users initialization!" << std::endl;
338 void WebUsers::saveActiveSessions()
342 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_ACTIVE_SESSIONS_FILE;
343 __COUT__ << fn << std::endl;
345 FILE *fp = fopen(fn.c_str(),
"w");
348 __COUT_ERR__ <<
"Error! Persistent active sessions could not be saved." << std::endl;
353 fprintf(fp,
"%d\n", version);
354 for (
unsigned int i = 0; i < ActiveSessionCookieCodeVector.size(); ++i)
362 fprintf(fp,
"%s\n", ActiveSessionCookieCodeVector[i].c_str());
363 fprintf(fp,
"%s\n", ActiveSessionIpVector[i].c_str());
364 fprintf(fp,
"%lu\n", ActiveSessionUserIdVector[i]);
365 fprintf(fp,
"%lu\n", ActiveSessionIndex[i]);
366 fprintf(fp,
"%ld\n", ActiveSessionStartTimeVector[i]);
369 __COUT__ <<
"ActiveSessionCookieCodeVector saved with size " <<
370 ActiveSessionCookieCodeVector.size() << std::endl;
378 void WebUsers::loadActiveSessions()
382 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_ACTIVE_SESSIONS_FILE;
383 __COUT__ << fn << std::endl;
384 FILE *fp = fopen(fn.c_str(),
"r");
387 __COUT_ERR__ <<
"Error! Persistent active sessions could not be saved." << std::endl;
393 const int LINELEN = 1000;
395 fgets(line, LINELEN, fp);
396 sscanf(line,
"%d", &version);
399 __COUT__ <<
"Extracting active sessions..." << std::endl;
403 while (fgets(line, LINELEN, fp))
405 if (strlen(line)) line[strlen(line) - 1] =
'\0';
406 if (strlen(line) != COOKIE_CODE_LENGTH)
408 __COUT__ <<
"Illegal cookie code found: " << line << std::endl;
413 ActiveSessionCookieCodeVector.push_back(line);
415 fgets(line, LINELEN, fp);
416 if (strlen(line)) line[strlen(line) - 1] =
'\0';
417 ActiveSessionIpVector.push_back(line);
419 fgets(line, LINELEN, fp);
420 ActiveSessionUserIdVector.push_back(uint64_t());
421 sscanf(line,
"%lu", &(ActiveSessionUserIdVector[ActiveSessionUserIdVector.size() - 1]));
423 fgets(line, LINELEN, fp);
424 ActiveSessionIndex.push_back(uint64_t());
425 sscanf(line,
"%lu", &(ActiveSessionIndex[ActiveSessionIndex.size() - 1]));
427 fgets(line, LINELEN, fp);
428 ActiveSessionStartTimeVector.push_back(time_t());
429 sscanf(line,
"%ld", &(ActiveSessionStartTimeVector[ActiveSessionStartTimeVector.size() - 1]));
440 __COUT__ <<
"ActiveSessionCookieCodeVector loaded with size " <<
441 ActiveSessionCookieCodeVector.size() << std::endl;
446 fp = fopen(fn.c_str(),
"w");
455 bool WebUsers::loadDatabases()
459 unsigned int LINE_LEN = 1000;
461 unsigned int i, si, c, len, f;
472 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_FILE;
473 __COUT__ << fn << std::endl;
474 fp = fopen(fn.c_str(),
"r");
477 mkdir(((std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_PATH).c_str(), 0755);
478 __COUT__ << ((std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_PATH).c_str() << std::endl;
479 fp = fopen(fn.c_str(), "w");
480 if (!fp) return false;
481 __COUT__ << "Hashes database created: " << fn << std::endl;
483 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING, "", DB_SAVE_OPEN);
484 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING, "", DB_SAVE_CLOSE);
491 while (fgets(line, LINE_LEN, fp))
493 if (strlen(line) < SHA512_DIGEST_LENGTH)
continue;
497 for (i = 0; i < len; ++i)
501 if (c != 2 && c != 4)
continue;
504 while (i < len && line[i] !=
'<') ++i;
513 HashesVector.push_back(&line[si]);
516 sscanf(&line[si],
"%lu", &tmpInt64);
517 HashesAccessTimeVector.push_back(tmpInt64);
521 __COUT__ << HashesAccessTimeVector.size() <<
" Hashes found." << std::endl;
535 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_FILE;
536 fp = fopen(fn.c_str(),
"r");
539 mkdir(((std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_PATH).c_str(), 0755);
540 __COUT__ << ((std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_PATH).c_str() << std::endl;
541 fp = fopen(fn.c_str(), "w");
542 if (!fp) return false;
543 __COUT__ << "Users database created: " << fn << std::endl;
545 saveToDatabase(fp, USERS_DB_GLOBAL_STRING, "", DB_SAVE_OPEN);
547 sprintf(nidStr, "%lu", usersNextUserId_);
548 saveToDatabase(fp, USERS_DB_NEXT_UID_STRING, nidStr, DB_SAVE_OPEN_AND_CLOSE);
549 saveToDatabase(fp, USERS_DB_GLOBAL_STRING, "", DB_SAVE_CLOSE);
552 createNewAccount(DEFAULT_ADMIN_USERNAME, DEFAULT_ADMIN_DISPLAY_NAME, DEFAULT_ADMIN_EMAIL);
559 char salt[] =
"nextUserId";
560 while (fgets(line, LINE_LEN, fp))
562 if (strlen(line) < strlen(salt) * 2)
continue;
564 for (i = 0; i < strlen(salt); ++i)
565 if (line[i + 1] != salt[i])
break;
567 if (i == strlen(salt))
571 while (i < LINE_LEN && line[i] !=
'\0' && line[i] !=
'<') ++i;
573 sscanf(&line[si],
"%lu", &usersNextUserId_);
578 __COUT__ <<
"Found Users database next user Id: " << usersNextUserId_ << std::endl;
581 while (fgets(line, LINE_LEN, fp))
583 if (strlen(line) < 30)
continue;
589 __COUT__ <<
"Line buffer too small: " << len << std::endl;
595 for (i = 0; i < len; ++i)
599 if (c == 0 || c % 2 == 1)
continue;
602 while (i < len && line[i] !=
'<') ++i;
611 UsersUsernameVector.push_back(&line[si]);
613 UsersDisplayNameVector.push_back(&line[si]);
615 UsersSaltVector.push_back(&line[si]);
618 sscanf(&line[si],
"%lu", &tmpInt64);
619 UsersUserIdVector.push_back(tmpInt64);
623 sscanf(&line[si],
"%lu", &tmpInt64);
624 UsersPermissionsVector.push_back(tmpInt64);
628 sscanf(&line[si],
"%lu", &tmpInt64);
629 UsersLastLoginAttemptVector.push_back(tmpInt64);
633 sscanf(&line[si],
"%lu", &tmpInt64);
634 UsersAccountCreatedTimeVector.push_back(tmpInt64);
638 sscanf(&line[si],
"%lu", &tmpInt64);
639 UsersLoginFailureCountVector.push_back(tmpInt64);
643 sscanf(&line[si],
"%lu", &tmpInt64);
644 UsersLastModifiedTimeVector.push_back(tmpInt64);
647 UsersLastModifierUsernameVector.push_back(&line[si]);
649 UsersUserEmailVector.push_back(&line[si]);
654 if (f && f != UsersDatabaseEntryFields.size() - 1)
656 if (f != 7 && f != 9)
658 __COUT__ <<
"FATAL ERROR - invalid database found with field number " << f << std::endl;
666 __COUT__ <<
"Update database to current version - adding fields: " <<
667 (UsersDatabaseEntryFields.size() - 1 - f) << std::endl;
669 UsersLastModifiedTimeVector.push_back(0);
670 UsersLastModifierUsernameVector.push_back(
"");
674 UsersUserEmailVector.push_back(
"");
681 __COUT__ << UsersLastModifiedTimeVector.size() <<
" Users found." << std::endl;
682 for (
size_t ii = 0; ii < UsersLastModifiedTimeVector.size(); ++ii)
684 __COUT__ <<
"User " << UsersUserIdVector[ii] <<
": Name: " << UsersUsernameVector[ii] <<
"\t\tDisplay Name: " << UsersDisplayNameVector[ii] <<
"\t\tEmail: " << UsersUserEmailVector[ii] <<
"\t\tPermissions: " << std::to_string(UsersPermissionsVector[ii]) << std::endl;
691 void WebUsers::saveToDatabase(FILE * fp, std::string field, std::string value, uint8_t type,
bool addNewLine)
695 std::string newLine = addNewLine ?
"\n" :
"";
697 if (type == DB_SAVE_OPEN_AND_CLOSE)
698 fprintf(fp,
"<%s>%s</%s>%s", field.c_str(), value.c_str(), field.c_str(), newLine.c_str());
699 else if (type == DB_SAVE_OPEN)
700 fprintf(fp,
"<%s>%s%s", field.c_str(), value.c_str(), newLine.c_str());
701 else if (type == DB_SAVE_CLOSE)
702 fprintf(fp,
"</%s>%s", field.c_str(), newLine.c_str());
713 bool WebUsers::saveDatabaseToFile(uint8_t db)
715 __COUT__ <<
"Save Database: " << (int)db << std::endl;
717 std::string fn = (std::string)WEB_LOGIN_DB_PATH +
718 ((db == DB_USERS) ? (std::string)USERS_DB_FILE : (std::string)HASHES_DB_FILE);
720 __COUT__ <<
"Save Database Filename: " << fn << std::endl;
726 sprintf(dayAppend,
".%lu.bkup", time(0) / (3600 * 24));
727 std::string bkup_fn = (std::string)WEB_LOGIN_DB_PATH +
728 (std::string)WEB_LOGIN_BKUP_DB_PATH +
729 ((db == DB_USERS) ? (std::string)USERS_DB_FILE : (std::
string)HASHES_DB_FILE) +
730 (std::
string)dayAppend;
732 __COUT__ << "Backup file: " << bkup_fn << std::endl;
734 std::
string shell_command = "mv " + fn + " " + bkup_fn;
735 system(shell_command.c_str());
738 FILE *fp = fopen(fn.c_str(), "wb");
739 if (!fp) return false;
745 saveToDatabase(fp, USERS_DB_GLOBAL_STRING,
"", DB_SAVE_OPEN);
747 sprintf(fldStr,
"%lu", usersNextUserId_);
748 saveToDatabase(fp, USERS_DB_NEXT_UID_STRING, fldStr, DB_SAVE_OPEN_AND_CLOSE);
750 __COUT__ <<
"Saving " << UsersUsernameVector.size() <<
" Users." << std::endl;
752 for (uint64_t i = 0; i < UsersUsernameVector.size(); ++i)
756 saveToDatabase(fp, USERS_DB_ENTRY_STRING,
"", DB_SAVE_OPEN,
false);
758 for (
unsigned int f = 0; f < UsersDatabaseEntryFields.size(); ++f)
762 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersUsernameVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
764 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersDisplayNameVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
766 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersSaltVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
769 sprintf(fldStr,
"%lu", UsersUserIdVector[i]);
770 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
774 sprintf(fldStr,
"%d", UsersPermissionsVector[i]);
775 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
779 sprintf(fldStr,
"%lu", UsersLastLoginAttemptVector[i]);
780 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
784 sprintf(fldStr,
"%lu", UsersAccountCreatedTimeVector[i]);
785 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
789 sprintf(fldStr,
"%d", UsersLoginFailureCountVector[i]);
790 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
794 sprintf(fldStr,
"%lu", UsersLastModifiedTimeVector[i]);
795 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
798 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersLastModifierUsernameVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
800 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersUserEmailVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
803 saveToDatabase(fp, USERS_DB_ENTRY_STRING,
"", DB_SAVE_CLOSE);
806 saveToDatabase(fp, USERS_DB_GLOBAL_STRING,
"", DB_SAVE_CLOSE);
811 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING,
"", DB_SAVE_OPEN);
813 __COUT__ <<
"Saving " << HashesVector.size() <<
" Hashes." << std::endl;
814 for (uint64_t i = 0; i < HashesVector.size(); ++i)
816 __COUT__ <<
"Saving " << HashesVector[i] <<
" Hashes." << std::endl;
817 saveToDatabase(fp, HASHES_DB_ENTRY_STRING,
"", DB_SAVE_OPEN,
false);
818 for (
unsigned int f = 0; f < HashesDatabaseEntryFields.size(); ++f)
821 saveToDatabase(fp, HashesDatabaseEntryFields[f], HashesVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
824 sprintf(fldStr,
"%lu", HashesAccessTimeVector[i]);
825 saveToDatabase(fp, HashesDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
828 saveToDatabase(fp, HASHES_DB_ENTRY_STRING,
"", DB_SAVE_CLOSE);
831 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING,
"", DB_SAVE_CLOSE);
846 bool WebUsers::createNewAccount(std::string Username, std::string DisplayName, std::string Email)
848 __COUT__ <<
"Creating account: " << Username << std::endl;
851 if ((i = searchUsersDatabaseForUsername(Username)) != NOT_FOUND_IN_DATABASE ||
852 Username == WebUsers::DEFAULT_ITERATOR_USERNAME)
854 __COUT__ <<
"Username: " << Username <<
" already exists" << std::endl;
859 UsersUsernameVector.push_back(Username);
860 UsersDisplayNameVector.push_back(DisplayName);
861 UsersUserEmailVector.push_back(Email);
862 UsersSaltVector.push_back(
"");
863 UsersPermissionsVector.push_back(UsersPermissionsVector.size() ? 0 : -1);
864 UsersUserIdVector.push_back(usersNextUserId_++);
865 if (usersNextUserId_ == (uint64_t)-1)
867 __COUT__ <<
"usersNextUserId_ wrap around!! Too many users??? Notify Admins." << std::endl;
868 usersNextUserId_ = 1;
870 UsersLastLoginAttemptVector.push_back(0);
871 UsersLoginFailureCountVector.push_back(0);
872 UsersAccountCreatedTimeVector.push_back(time(0));
873 UsersLastModifiedTimeVector.push_back(0);
874 UsersLastModifierUsernameVector.push_back(
"");
876 return saveDatabaseToFile(DB_USERS);
885 bool WebUsers::deleteAccount(std::string username, std::string displayName)
887 uint64_t i = searchUsersDatabaseForUsername(username);
888 if (i == NOT_FOUND_IN_DATABASE)
return false;
889 if (UsersDisplayNameVector[i] != displayName)
return false;
893 UsersUsernameVector.erase(UsersUsernameVector.begin() + i);
894 UsersUserEmailVector.erase(UsersUserEmailVector.begin() + i);
895 UsersDisplayNameVector.erase(UsersDisplayNameVector.begin() + i);
896 UsersSaltVector.erase(UsersSaltVector.begin() + i);
897 UsersPermissionsVector.erase(UsersPermissionsVector.begin() + i);
898 UsersUserIdVector.erase(UsersUserIdVector.begin() + i);
899 UsersLastLoginAttemptVector.erase(UsersLastLoginAttemptVector.begin() + i);
900 UsersAccountCreatedTimeVector.erase(UsersAccountCreatedTimeVector.begin() + i);
901 UsersLoginFailureCountVector.erase(UsersLoginFailureCountVector.begin() + i);
902 UsersLastModifierUsernameVector.erase(UsersLastModifierUsernameVector.begin() + i);
903 UsersLastModifiedTimeVector.erase(UsersLastModifiedTimeVector.begin() + i);
906 return saveDatabaseToFile(DB_USERS);
910 unsigned int WebUsers::hexByteStrToInt(
const char *h)
913 char hs[3] = { h[0],h[1],
'\0' };
914 sscanf(hs,
"%X", &rv);
919 void WebUsers::intToHexStr(
unsigned char i,
char *h)
921 sprintf(h,
"%2.2X", i);
933 uint64_t WebUsers::attemptActiveSession(std::string uuid, std::string &jumbledUser,
934 std::string jumbledPw, std::string &newAccountCode)
936 cleanupExpiredEntries();
938 if (!CareAboutCookieCodes_)
940 uint64_t uid = getAdminUserID();
941 jumbledUser = getUsersDisplayName(uid);
942 newAccountCode = genCookieCode();
949 if ((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
951 __COUT__ <<
"uuid: " << uuid <<
" is not found" << std::endl;
952 newAccountCode =
"1";
953 return NOT_FOUND_IN_DATABASE;
955 ++LoginSessionAttemptsVector[i];
957 std::string user = dejumble(jumbledUser, LoginSessionIdVector[i]);
958 __COUT__ <<
"DejumbledUser = " << user << std::endl;
959 std::string pw = dejumble(jumbledPw, LoginSessionIdVector[i]);
962 if ((i = searchUsersDatabaseForUsername(user)) == NOT_FOUND_IN_DATABASE)
964 __COUT__ <<
"user: " << user <<
" is not found" << std::endl;
965 return NOT_FOUND_IN_DATABASE;
968 UsersLastLoginAttemptVector[i] = time(0);
969 if (!UsersPermissionsVector[i])
971 __COUT__ <<
"user: " << user <<
" account INACTIVE (could be due to failed logins)" << std::endl;
972 return NOT_FOUND_IN_DATABASE;
975 if (UsersSaltVector[i] ==
"")
977 __COUT__ <<
"First login attempt for user: " << user << std::endl;
979 char charTimeStr[10];
980 sprintf(charTimeStr,
"%d",
int(UsersAccountCreatedTimeVector[i] & 0xffff));
981 std::string tmpTimeStr = charTimeStr;
982 if (newAccountCode != tmpTimeStr)
984 __COUT__ <<
"New account code did not match: " << tmpTimeStr <<
" != " << newAccountCode << std::endl;
985 saveDatabaseToFile(DB_USERS);
986 return NOT_FOUND_IN_DATABASE;
992 while (!addToHashesDatabase(sha512(user, pw, UsersSaltVector[i])))
996 UsersSaltVector[i] =
"";
1000 __COUT__ <<
"\tHash added: " << HashesVector[HashesVector.size() - 1] << std::endl;
1004 std::string salt = UsersSaltVector[i];
1006 if (searchHashesDatabaseForHash(sha512(user, pw, salt)) == NOT_FOUND_IN_DATABASE)
1008 __COUT__ <<
"not found?" << std::endl;
1009 ++UsersLoginFailureCountVector[i];
1010 if (UsersLoginFailureCountVector[i] >= USERS_MAX_LOGIN_FAILURES)
1011 UsersPermissionsVector[i] = 0;
1013 __COUT__ <<
"\tUser/pw for user: " << user <<
" was not correct Failed Attempt #" << (int)(UsersLoginFailureCountVector[i]) << std::endl;
1014 if (!UsersPermissionsVector[i])
1015 __COUT__ <<
"Account is locked!" << std::endl;
1017 saveDatabaseToFile(DB_USERS);
1018 return NOT_FOUND_IN_DATABASE;
1022 __COUT__ <<
"Login successful for: " << user << std::endl;
1024 UsersLoginFailureCountVector[i] = 0;
1027 for (
int h = 0; h < 2; ++h)
1029 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_LOGIN_HISTORY_PATH + (h ? USERS_GLOBAL_HISTORY_FILE : UsersUsernameVector[i])
1030 +
"." + (std::string)USERS_LOGIN_HISTORY_FILETYPE;
1034 if (histXml.loadXmlDocument(fn))
1036 while (histXml.getChildrenCount() + 1 > (h ? USERS_GLOBAL_HISTORY_SIZE : USERS_LOGIN_HISTORY_SIZE))
1037 histXml.removeDataElement();
1040 __COUT__ <<
"No previous login history found." << std::endl;
1045 sprintf(entryStr,
"Time=%lu Username=%s Permissions=%d UID=%lu",
1046 time(0), UsersUsernameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1048 sprintf(entryStr,
"Time=%lu DisplayName=%s Permissions=%d UID=%lu",
1049 time(0), UsersDisplayNameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1050 histXml.addTextElementToData(PREF_XML_LOGIN_HISTORY_FIELD, entryStr);
1053 histXml.saveXmlDocument(fn);
1057 saveDatabaseToFile(DB_USERS);
1058 jumbledUser = UsersDisplayNameVector[i];
1059 newAccountCode = createNewActiveSession(UsersUserIdVector[i]);
1060 return UsersUserIdVector[i];
1068 uint64_t WebUsers::attemptActiveSessionWithCert(std::string uuid, std::string &email,
1069 std::string &cookieCode, std::string& user)
1071 cleanupExpiredEntries();
1073 if (!CareAboutCookieCodes_)
1075 uint64_t uid = getAdminUserID();
1076 email = getUsersDisplayName(uid);
1077 cookieCode = genCookieCode();
1083 __COUT__ <<
"Rejecting logon with blank fingerprint" << std::endl;
1084 return NOT_FOUND_IN_DATABASE;
1090 if ((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
1092 __COUT__ <<
"uuid: " << uuid <<
" is not found" << std::endl;
1094 return NOT_FOUND_IN_DATABASE;
1096 ++LoginSessionAttemptsVector[i];
1098 email = getUserEmailFromFingerprint(email);
1099 __COUT__ <<
"DejumbledEmail = " << email << std::endl;
1102 __COUT__ <<
"Rejecting logon with unknown fingerprint" << std::endl;
1103 return NOT_FOUND_IN_DATABASE;
1107 if ((i = searchUsersDatabaseForUserEmail(email)) == NOT_FOUND_IN_DATABASE)
1109 __COUT__ <<
"email: " << email <<
" is not found" << std::endl;
1110 return NOT_FOUND_IN_DATABASE;
1113 user = getUsersUsername(i);
1115 UsersLastLoginAttemptVector[i] = time(0);
1116 if (!UsersPermissionsVector[i])
1118 __COUT__ <<
"user: " << user <<
" account INACTIVE (could be due to failed logins)" << std::endl;
1119 return NOT_FOUND_IN_DATABASE;
1122 if (UsersSaltVector[i] ==
"")
1124 return NOT_FOUND_IN_DATABASE;
1127 __COUT__ <<
"Login successful for: " << user << std::endl;
1129 UsersLoginFailureCountVector[i] = 0;
1132 for (
int h = 0; h < 2; ++h)
1134 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_LOGIN_HISTORY_PATH + (h ? USERS_GLOBAL_HISTORY_FILE : UsersUsernameVector[i])
1135 +
"." + (std::string)USERS_LOGIN_HISTORY_FILETYPE;
1139 if (histXml.loadXmlDocument(fn))
1141 while (histXml.getChildrenCount() + 1 > (h ? USERS_GLOBAL_HISTORY_SIZE : USERS_LOGIN_HISTORY_SIZE))
1142 histXml.removeDataElement();
1145 __COUT__ <<
"No previous login history found." << std::endl;
1150 sprintf(entryStr,
"Time=%lu Username=%s Permissions=%d UID=%lu",
1151 time(0), UsersUsernameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1153 sprintf(entryStr,
"Time=%lu DisplayName=%s Permissions=%d UID=%lu",
1154 time(0), UsersDisplayNameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1155 histXml.addTextElementToData(PREF_XML_LOGIN_HISTORY_FIELD, entryStr);
1158 histXml.saveXmlDocument(fn);
1162 saveDatabaseToFile(DB_USERS);
1163 email = UsersDisplayNameVector[i];
1164 cookieCode = createNewActiveSession(UsersUserIdVector[i]);
1165 return UsersUserIdVector[i];
1171 uint64_t WebUsers::searchActiveSessionDatabaseForCookie(std::string cookieCode)
const
1174 for (; i < ActiveSessionCookieCodeVector.size(); ++i)
1175 if (ActiveSessionCookieCodeVector[i] == cookieCode)
break;
1176 return (i == ActiveSessionCookieCodeVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1183 bool WebUsers::isUsernameActive(std::string username)
const
1186 if ((u = searchUsersDatabaseForUsername(username)) == NOT_FOUND_IN_DATABASE)
return false;
1187 return isUserIdActive(UsersUserIdVector[u]);
1194 bool WebUsers::isUserIdActive(uint64_t uid)
const
1197 for (; i < ActiveSessionUserIdVector.size(); ++i)
1198 if (ActiveSessionUserIdVector[i] == uid)
return true;
1205 uint64_t WebUsers::searchUsersDatabaseForUsername(std::string username)
const
1208 for (; i < UsersUsernameVector.size(); ++i)
1209 if (UsersUsernameVector[i] == username)
break;
1210 return (i == UsersUsernameVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1216 uint64_t WebUsers::searchUsersDatabaseForUserEmail(std::string useremail)
const
1219 for (; i < UsersUserEmailVector.size(); ++i)
1220 if (UsersUserEmailVector[i] == useremail)
break;
1221 return (i == UsersUserEmailVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1227 uint64_t WebUsers::searchUsersDatabaseForUserId(uint64_t uid)
const
1230 for (; i < UsersUserIdVector.size(); ++i)
1231 if (UsersUserIdVector[i] == uid)
break;
1232 return (i == UsersUserIdVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1238 uint64_t WebUsers::searchLoginSessionDatabaseForUUID(std::string uuid)
const
1241 for (; i < LoginSessionUUIDVector.size(); ++i)
1242 if (LoginSessionUUIDVector[i] == uuid)
break;
1243 return (i == LoginSessionUUIDVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1249 uint64_t WebUsers::searchHashesDatabaseForHash(std::string hash)
1254 for (; i < HashesVector.size(); ++i)
1255 if (HashesVector[i] == hash)
break;
1259 if (i < HashesAccessTimeVector.size())
1260 HashesAccessTimeVector.push_back((time(0) + (rand() % 2 ? 1 : -1)*(rand() % 30 * 24 * 60 * 60)) & 0x0FFFFFFFFFE000000);
1263 return (i == HashesVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1270 bool WebUsers::addToHashesDatabase(std::string hash)
1272 if (searchHashesDatabaseForHash(hash) != NOT_FOUND_IN_DATABASE)
1274 __COUT__ <<
"Hash collision: " << hash << std::endl;
1277 HashesVector.push_back(hash);
1278 HashesAccessTimeVector.push_back((time(0) + (rand() % 2 ? 1 : -1)*(rand() % 30 * 24 * 60 * 60)) & 0x0FFFFFFFFFE000000);
1280 return saveDatabaseToFile(DB_HASHES);
1285 std::string WebUsers::genCookieCode()
1288 std::string cc =
"";
1289 for (uint32_t i = 0; i < COOKIE_CODE_LENGTH / 2; ++i)
1291 intToHexStr(rand(), hexStr);
1299 void WebUsers::removeLoginSessionEntry(
unsigned int i)
1301 LoginSessionIdVector.erase(LoginSessionIdVector.begin() + i);
1302 LoginSessionUUIDVector.erase(LoginSessionUUIDVector.begin() + i);
1303 LoginSessionIpVector.erase(LoginSessionIpVector.begin() + i);
1304 LoginSessionStartTimeVector.erase(LoginSessionStartTimeVector.begin() + i);
1305 LoginSessionAttemptsVector.erase(LoginSessionAttemptsVector.begin() + i);
1312 std::string WebUsers::createNewActiveSession(uint64_t uid, std::string ip, uint64_t asIndex)
1314 ActiveSessionCookieCodeVector.push_back(genCookieCode());
1315 ActiveSessionIpVector.push_back(ip);
1316 ActiveSessionUserIdVector.push_back(uid);
1317 ActiveSessionStartTimeVector.push_back(time(0));
1320 ActiveSessionIndex.push_back(asIndex);
1325 for (uint64_t j = 0; j < ActiveSessionIndex.size(); ++j)
1326 if (ActiveSessionUserIdVector[j] == uid && max < ActiveSessionIndex[j])
1327 max = ActiveSessionIndex[j];
1329 ActiveSessionIndex.push_back(max ? max + 1 : 1);
1332 return ActiveSessionCookieCodeVector[ActiveSessionCookieCodeVector.size() - 1];
1337 void WebUsers::removeActiveSessionEntry(
unsigned int i)
1339 ActiveSessionCookieCodeVector.erase(ActiveSessionCookieCodeVector.begin() + i);
1340 ActiveSessionIpVector.erase(ActiveSessionIpVector.begin() + i);
1341 ActiveSessionUserIdVector.erase(ActiveSessionUserIdVector.begin() + i);
1342 ActiveSessionStartTimeVector.erase(ActiveSessionStartTimeVector.begin() + i);
1343 ActiveSessionIndex.erase(ActiveSessionIndex.begin() + i);
1369 std::string WebUsers::refreshCookieCode(
unsigned int i,
bool enableRefresh)
1372 for (uint64_t j = ActiveSessionUserIdVector.size() - 1; j != (uint64_t)-1; --j)
1373 if (ActiveSessionUserIdVector[j] == ActiveSessionUserIdVector[i] &&
1374 ActiveSessionIndex[j] == ActiveSessionIndex[i])
1379 if (enableRefresh && (time(0) - ActiveSessionStartTimeVector[j] > ACTIVE_SESSION_EXPIRATION_TIME / 2))
1382 ActiveSessionStartTimeVector[j] = time(0) - ACTIVE_SESSION_EXPIRATION_TIME +
1383 ACTIVE_SESSION_COOKIE_OVERLAP_TIME;
1386 return createNewActiveSession(ActiveSessionUserIdVector[i], ActiveSessionIpVector[i], ActiveSessionIndex[i]);
1389 return ActiveSessionCookieCodeVector[j];
1400 uint64_t WebUsers::isCookieCodeActiveForLogin(std::string uuid, std::string &cookieCode,
1401 std::string &username)
1403 if (!CareAboutCookieCodes_)
1404 return getAdminUserID();
1409 if (!ActiveSessionStartTimeVector.size())
return NOT_FOUND_IN_DATABASE;
1414 if ((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
1416 __COUT__ <<
"uuid not found: " << uuid << std::endl;
1417 return NOT_FOUND_IN_DATABASE;
1420 username = dejumble(username, LoginSessionIdVector[i]);
1423 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1425 __COUT__ <<
"Cookie code not found" << std::endl;
1426 return NOT_FOUND_IN_DATABASE;
1430 if ((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
1432 __COUT__ <<
"User ID not found" << std::endl;
1433 return NOT_FOUND_IN_DATABASE;
1437 if (UsersUsernameVector[j] != username)
1440 __COUT__ <<
"cookieCode: " << cookieCode <<
" was.." << std::endl;
1441 __COUT__ <<
"username: " << username <<
" is not found" << std::endl;
1442 return NOT_FOUND_IN_DATABASE;
1445 username = UsersDisplayNameVector[j];
1446 cookieCode = refreshCookieCode(i);
1447 return UsersUserIdVector[j];
1453 uint64_t WebUsers::getActiveSessionCountForUser(uint64_t uid)
1456 std::vector<uint64_t> uniqueAsi;
1459 for (i = 0; i < ActiveSessionUserIdVector.size(); ++i)
1460 if (ActiveSessionUserIdVector[i] == uid)
1465 for (j = 0; j < uniqueAsi.size(); ++j)
1466 if (uniqueAsi[j] == ActiveSessionIndex[i])
1468 unique =
false;
break;
1472 uniqueAsi.push_back(ActiveSessionIndex[i]);
1475 __COUT__ <<
"Found " << uniqueAsi.size() <<
" active sessions for uid " << uid << std::endl;
1477 return uniqueAsi.size();
1482 std::string WebUsers::getUsersDisplayName(uint64_t uid)
1485 if ((i = searchUsersDatabaseForUserId(uid)) == NOT_FOUND_IN_DATABASE)
return "";
1486 return UsersDisplayNameVector[i];
1491 std::string WebUsers::getUsersUsername(uint64_t uid)
1494 if ((i = searchUsersDatabaseForUserId(uid)) == NOT_FOUND_IN_DATABASE)
return "";
1495 return UsersUsernameVector[i];
1508 uint64_t WebUsers::cookieCodeLogout(std::string cookieCode,
bool logoutOtherUserSessions, uint64_t *userId, std::string ip)
1515 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1517 __COUT__ <<
"Cookie code not found" << std::endl;
1518 return NOT_FOUND_IN_DATABASE;
1522 if (ActiveSessionIpVector[i] != ip)
1524 __COUT__ <<
"IP does not match active session" << std::endl;
1525 return NOT_FOUND_IN_DATABASE;
1534 uint64_t asi = ActiveSessionIndex[i];
1535 uint64_t uid = ActiveSessionUserIdVector[i];
1536 if (userId) *userId = uid;
1537 uint64_t logoutCount = 0;
1540 while (i < ActiveSessionIndex.size())
1542 if ((logoutOtherUserSessions && ActiveSessionUserIdVector[i] == uid &&
1543 ActiveSessionIndex[i] != asi) ||
1544 (!logoutOtherUserSessions && ActiveSessionUserIdVector[i] == uid &&
1545 ActiveSessionIndex[i] == asi))
1547 __COUT__ <<
"Logging out of active session " << ActiveSessionUserIdVector[i]
1548 <<
"-" << ActiveSessionIndex[i] << std::endl;
1549 removeActiveSessionEntry(i);
1556 __COUT__ <<
"Found and removed active session count = " << logoutCount << std::endl;
1563 bool WebUsers::getUserInfoForCookie(std::string &cookieCode,
1564 std::string *userName, std::string *displayName,
1565 uint64_t *activeSessionIndex)
1567 if (userName) *userName =
"";
1568 if (displayName) *displayName =
"";
1570 if (!CareAboutCookieCodes_)
1572 uint64_t uid = getAdminUserID();
1573 if (userName) *userName = getUsersUsername(uid);
1574 if (displayName) *displayName = getUsersDisplayName(uid);
1575 if (activeSessionIndex) *activeSessionIndex = -1;
1582 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1584 __COUT__ <<
"cookieCode NOT_FOUND_IN_DATABASE" << std::endl;
1589 if ((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
1591 __COUT__ <<
"ActiveSessionUserIdVector NOT_FOUND_IN_DATABASE" << std::endl;
1595 if (userName) *userName = UsersUsernameVector[j];
1596 if (displayName) *displayName = UsersDisplayNameVector[j];
1597 if (activeSessionIndex) *activeSessionIndex = ActiveSessionIndex[i];
1612 bool WebUsers::cookieCodeIsActiveForRequest(std::string &cookieCode,
1613 uint8_t *userPermissions, uint64_t *uid, std::string ip,
1614 bool refresh, std::string *userWithLock)
1617 cleanupExpiredEntries();
1624 if (!CareAboutCookieCodes_)
1626 if (userPermissions) *userPermissions = -1;
1627 if (uid) *uid = getAdminUserID();
1628 if (userWithLock) *userWithLock = usersUsernameWithLock_;
1630 if(cookieCode.size() != COOKIE_CODE_LENGTH)
1631 cookieCode = genCookieCode();
1638 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1640 __COUT__ <<
"Cookie code not found" << std::endl;
1641 cookieCode = REQ_NO_LOGIN_RESPONSE;
1646 if (ActiveSessionIpVector[i] != ip)
1648 __COUT__ <<
"IP does not match active session" << std::endl;
1649 cookieCode = REQ_NO_LOGIN_RESPONSE;
1654 if ((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
1656 __COUT__ <<
"User ID not found" << std::endl;
1657 cookieCode = REQ_NO_LOGIN_RESPONSE;
1661 uint8_t tmpPerm = getPermissionsForUser(UsersUserIdVector[j]);
1665 cookieCode = REQ_NO_PERMISSION_RESPONSE;
1670 if (userPermissions) *userPermissions = tmpPerm;
1671 if (uid) *uid = UsersUserIdVector[j];
1672 if (userWithLock) *userWithLock = usersUsernameWithLock_;
1674 cookieCode = refreshCookieCode(i, refresh);
1685 void WebUsers::cleanupExpiredEntries(std::vector<std::string> *loggedOutUsernames)
1690 if (loggedOutUsernames)
1692 for (i = 0; i < UsersLoggedOutUsernames_.size(); ++i)
1693 loggedOutUsernames->push_back(UsersLoggedOutUsernames_[i]);
1694 UsersLoggedOutUsernames_.clear();
1700 for (i = 0; i < LoginSessionStartTimeVector.size(); ++i)
1701 if (LoginSessionStartTimeVector[i] + LOGIN_SESSION_EXPIRATION_TIME < time(0) ||
1702 LoginSessionAttemptsVector[i] > LOGIN_SESSION_ATTEMPTS_MAX)
1707 removeLoginSessionEntry(i);
1720 for (i = 0; i < ActiveSessionStartTimeVector.size(); ++i)
1721 if (ActiveSessionStartTimeVector[i] + ACTIVE_SESSION_EXPIRATION_TIME <= time(0))
1728 tmpUid = ActiveSessionUserIdVector[i];
1729 removeActiveSessionEntry(i);
1733 if (!isUserIdActive(tmpUid))
1735 if (loggedOutUsernames)
1736 loggedOutUsernames->push_back(UsersUsernameVector[searchUsersDatabaseForUserId(tmpUid)]);
1738 UsersLoggedOutUsernames_.push_back(UsersUsernameVector[searchUsersDatabaseForUserId(tmpUid)]);
1755 if (CareAboutCookieCodes_ && !isUsernameActive(usersUsernameWithLock_))
1756 usersUsernameWithLock_ =
"";
1766 std::string WebUsers::createNewLoginSession(std::string UUID, std::string ip)
1768 __COUT__ <<
"UUID: " << UUID << std::endl << std::endl;
1770 for (; i < LoginSessionUUIDVector.size(); ++i)
1771 if (LoginSessionUUIDVector[i] == UUID)
break;
1773 if (i != LoginSessionUUIDVector.size())
1775 __COUT__ <<
"UUID: " << UUID <<
" is not unique" << std::endl;
1780 LoginSessionUUIDVector.push_back(UUID);
1784 std::string sid =
"";
1785 for (i = 0; i < SESSION_ID_LENGTH / 2; ++i)
1787 intToHexStr(rand(), hexStr);
1790 LoginSessionIdVector.push_back(sid);
1791 LoginSessionIpVector.push_back(
"");
1792 LoginSessionStartTimeVector.push_back(time(0));
1793 LoginSessionAttemptsVector.push_back(0);
1805 std::string WebUsers::sha512(std::string user, std::string password, std::string &salt)
1807 SHA512_CTX sha512_context;
1812 SHA512_Init(&sha512_context);
1814 for (
unsigned int i = 0; i < 8; ++i)
1815 sha512_context.h[i] += rand();
1817 for (
unsigned int i = 0; i <
sizeof(SHA512_CTX); ++i)
1819 intToHexStr((uint8_t)(((uint8_t *)(&sha512_context))[i]), hexStr);
1821 salt.append(hexStr);
1830 for (
unsigned int i = 0; i <
sizeof(SHA512_CTX); ++i)
1831 ((uint8_t *)(&sha512_context))[i] = hexByteStrToInt(&(salt.c_str()[i * 2]));
1834 std::string strToHash = salt + user + password;
1837 unsigned char hash[SHA512_DIGEST_LENGTH];
1839 char retHash[SHA512_DIGEST_LENGTH * 2 + 1];
1844 SHA512_Update(&sha512_context, strToHash.c_str(), strToHash.length());
1846 SHA512_Final(hash, &sha512_context);
1850 for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
1851 sprintf(retHash + (i * 2),
"%02x", hash[i]);
1854 retHash[SHA512_DIGEST_LENGTH * 2] =
'\0';
1868 std::string WebUsers::dejumble(std::string u, std::string s)
1871 if (s.length() != SESSION_ID_LENGTH)
return "";
1873 int ss = s.length() / 2;
1874 int p = hexByteStrToInt(&(s.c_str()[0])) % ss;
1875 int n = hexByteStrToInt(&(s.c_str()[p * 2])) % ss;
1876 int len = (hexByteStrToInt(&(u.c_str()[p * 2])) - p - n + ss * 3) % ss;
1879 for (
int i = 0; i < ss; ++i) x[i] = 0;
1882 int c = hexByteStrToInt(&(u.c_str()[p * 2]));
1884 std::string user =
"";
1886 for (
int l = 0; l < len; ++l)
1888 p = (p + hexByteStrToInt(&(s.c_str()[p * 2]))) % ss;
1889 while (x[p]) p = (p + 1) % ss;
1891 n = hexByteStrToInt(&(s.c_str()[p * 2]));
1892 user.append(1, (hexByteStrToInt(&(u.c_str()[p * 2])) - c - n + ss * 4) % ss);
1893 c = hexByteStrToInt(&(u.c_str()[p * 2]));
1902 uint8_t WebUsers::getPermissionsForUser(uint64_t uid)
1904 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
1905 return (userIndex < UsersPermissionsVector.size()) ? UsersPermissionsVector[userIndex] : 0;
1912 std::string WebUsers::getTooltipFilename(
1913 const std::string& username,
const std::string &srcFile,
1914 const std::string &srcFunc,
const std::string &srcId)
1916 std::string filename = (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH +
"/";
1920 mkdir(((std::string)WEB_LOGIN_DB_PATH).c_str(), 0755);
1921 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH).c_str(), 0755);
1922 mkdir(filename.c_str(), 0755);
1924 for (
const char& c : username)
1926 (c >=
'a' && c <=
'z') ||
1927 (c >=
'A' && c <=
'Z') ||
1928 (c >=
'0' && c <=
'9'))
1933 mkdir(filename.c_str(), 0755);
1935 for (
const char& c : srcFile)
1937 (c >=
'a' && c <=
'z') ||
1938 (c >=
'A' && c <=
'Z') ||
1939 (c >=
'0' && c <=
'9'))
1942 for (
const char& c : srcFunc)
1944 (c >=
'a' && c <=
'z') ||
1945 (c >=
'A' && c <=
'Z') ||
1946 (c >=
'0' && c <=
'9'))
1949 for (
const char& c : srcId)
1951 (c >=
'a' && c <=
'z') ||
1952 (c >=
'A' && c <=
'Z') ||
1953 (c >=
'0' && c <=
'9'))
1956 __COUT__ <<
"filename " << filename << std::endl;
1960 std::string ots::WebUsers::getUserEmailFromFingerprint(std::string fingerprint)
1962 std::ifstream f(WEB_LOGIN_CERTDATA_PATH);
1969 certFingerprints_[email] = fp;
1971 remove(WEB_LOGIN_CERTDATA_PATH.c_str());
1974 for (
auto fp : certFingerprints_)
1976 if (fp.second == fingerprint)
return fp.first;
1984 void WebUsers::tooltipSetNeverShowForUsername(
const std::string& username,
1986 const std::string &srcFile,
const std::string &srcFunc,
1987 const std::string &srcId,
bool doNeverShow,
bool temporarySilence)
1990 __COUT__ <<
"Setting tooltip never show for user: " << username <<
1991 " to " << doNeverShow <<
" (temporarySilence=" <<
1992 temporarySilence <<
")" << std::endl;
1995 std::string filename = getTooltipFilename(username, srcFile, srcFunc, srcId);
1996 FILE *fp = fopen(filename.c_str(),
"w");
1999 if (temporarySilence)
2000 fprintf(fp,
"%ld", time(0) + 60 * 60);
2002 fputc(doNeverShow ?
'1' :
'0', fp);
2006 __COUT_ERR__ <<
"Big problme with tooltips! File not accessible: " << filename << std::endl;
2016 void WebUsers::tooltipCheckForUsername(
const std::string& username,
2018 const std::string &srcFile,
const std::string &srcFunc,
2019 const std::string &srcId)
2021 if (srcId ==
"ALWAYS")
2024 xmldoc->addTextElementToData(
"ShowTooltip",
"1");
2032 __COUT__ <<
"Checking tooltip for user: " << username << std::endl;
2036 std::string filename = getTooltipFilename(username, srcFile, srcFunc, srcId);
2037 FILE *fp = fopen(filename.c_str(),
"r");
2042 fgets(line, 100, fp);
2044 sscanf(line,
"%ld", &val);
2045 __COUT__ <<
"tooltip value read = " << val << std::endl;
2050 xmldoc->addTextElementToData(
"ShowTooltip", val == 1 ?
"0" :
2051 (time(0) > val ?
"1" :
"0"));
2054 xmldoc->addTextElementToData(
"ShowTooltip",
"1");
2059 void WebUsers::resetAllUserTooltips(
const std::string &userNeedle)
2061 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH +
2062 "/" + userNeedle).c_str());
2063 __COUT__ <<
"Successfully reset Tooltips for user " << userNeedle << std::endl;
2084 void WebUsers::insertSettingsForUser(uint64_t uid,
HttpXmlDocument *xmldoc,
bool includeAccounts)
2086 uint8_t p = getPermissionsForUser(uid);
2089 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2090 __COUT__ <<
"Gettings settings for user: " << UsersUsernameVector[userIndex] << std::endl;
2092 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH + UsersUsernameVector[userIndex] +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2096 __COUT__ <<
"Preferences file: " << fn << std::endl;
2098 if (!prefXml.loadXmlDocument(fn))
2100 __COUT__ <<
"Preferences are defaults." << std::endl;
2102 xmldoc->addTextElementToData(PREF_XML_BGCOLOR_FIELD, PREF_XML_BGCOLOR_DEFAULT);
2103 xmldoc->addTextElementToData(PREF_XML_DBCOLOR_FIELD, PREF_XML_DBCOLOR_DEFAULT);
2104 xmldoc->addTextElementToData(PREF_XML_WINCOLOR_FIELD, PREF_XML_WINCOLOR_DEFAULT);
2105 xmldoc->addTextElementToData(PREF_XML_LAYOUT_FIELD, PREF_XML_LAYOUT_DEFAULT);
2109 __COUT__ <<
"Saved Preferences found." << std::endl;
2110 xmldoc->copyDataChildren(prefXml);
2116 if (includeAccounts && p == (uint8_t)-1)
2119 __COUT__ <<
"Super User on our hands" << std::endl;
2121 xmldoc->addTextElementToData(PREF_XML_ACCOUNTS_FIELD,
"");
2125 for (uint64_t i = 0; i < UsersUsernameVector.size(); ++i)
2127 xmldoc->addTextElementToParent(
"username", UsersUsernameVector[i], PREF_XML_ACCOUNTS_FIELD);
2128 xmldoc->addTextElementToParent(
"display_name", UsersDisplayNameVector[i], PREF_XML_ACCOUNTS_FIELD);
2129 if (UsersUserEmailVector.size() > i)
2131 xmldoc->addTextElementToParent(
"useremail", UsersUserEmailVector[i], PREF_XML_ACCOUNTS_FIELD);
2135 xmldoc->addTextElementToParent(
"useremail",
"", PREF_XML_ACCOUNTS_FIELD);
2138 sprintf(permStr,
"%d", UsersPermissionsVector[i]);
2139 xmldoc->addTextElementToParent(
"permissions", permStr, PREF_XML_ACCOUNTS_FIELD);
2140 if (UsersSaltVector[i] ==
"")
2141 sprintf(permStr,
"%d",
int(UsersAccountCreatedTimeVector[i] & 0xffff));
2144 xmldoc->addTextElementToParent(
"nac", permStr, PREF_XML_ACCOUNTS_FIELD);
2149 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2150 (std::string)SYSTEM_PREFERENCES_PREFIX +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2151 if (!prefXml.loadXmlDocument(fn))
2153 __COUT__ <<
"System Preferences are defaults." << std::endl;
2155 xmldoc->addTextElementToData(PREF_XML_SYSLAYOUT_FIELD, PREF_XML_SYSLAYOUT_DEFAULT);
2159 __COUT__ <<
"Saved System Preferences found." << std::endl;
2160 xmldoc->copyDataChildren(prefXml);
2164 sprintf(permStr,
"%d", p);
2165 xmldoc->addTextElementToData(PREF_XML_PERMISSIONS_FIELD, permStr);
2168 xmldoc->addTextElementToData(PREF_XML_USERLOCK_FIELD, usersUsernameWithLock_);
2170 xmldoc->addTextElementToData(PREF_XML_USERNAME_FIELD, getUsersUsername(uid));
2176 void WebUsers::setGenericPreference(uint64_t uid,
const std::string &preferenceName,
2177 const std::string &preferenceValue)
2179 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2183 std::string safePreferenceName =
"";
2184 for (
const auto &c : preferenceName)
2185 if ((c >=
'a' && c <=
'z') ||
2186 (c >=
'A' && c <=
'Z') ||
2187 (c >=
'0' && c <=
'9') ||
2188 (c >=
'-' || c <=
'_'))
2189 safePreferenceName += c;
2191 std::string dir = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2192 "generic_" + safePreferenceName +
"/";
2195 mkdir(dir.c_str(), 0755);
2197 std::string fn = UsersUsernameVector[userIndex] +
"_" + safePreferenceName +
2198 "." + (std::string)USERS_PREFERENCES_FILETYPE;
2200 __COUT__ <<
"Preferences file: " << (dir + fn) << std::endl;
2202 FILE *fp = fopen((dir + fn).c_str(),
"w");
2205 fprintf(fp,
"%s", preferenceValue.c_str());
2209 __COUT_ERR__ <<
"Preferences file could not be opened for writing!" << std::endl;
2216 std::string WebUsers::getGenericPreference(uint64_t uid,
const std::string &preferenceName,
2219 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2223 std::string safePreferenceName =
"";
2224 for (
const auto &c : preferenceName)
2225 if ((c >=
'a' && c <=
'z') ||
2226 (c >=
'A' && c <=
'Z') ||
2227 (c >=
'0' && c <=
'9') ||
2228 (c >=
'-' || c <=
'_'))
2229 safePreferenceName += c;
2231 std::string dir = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2232 "generic_" + safePreferenceName +
"/";
2234 std::string fn = UsersUsernameVector[userIndex] +
"_" + safePreferenceName +
2235 "." + (std::string)USERS_PREFERENCES_FILETYPE;
2237 __COUT__ <<
"Preferences file: " << (dir + fn) << std::endl;
2240 FILE *fp = fopen((dir + fn).c_str(),
"rb");
2243 fseek(fp, 0, SEEK_END);
2244 long size = ftell(fp);
2245 char line[size + 1];
2247 fgets(line, size + 1, fp);
2250 __COUT__ <<
"Read value " << line << std::endl;
2251 if (xmldoc) xmldoc->addTextElementToData(safePreferenceName, line);
2255 __COUT__ <<
"Using default value." << std::endl;
2258 if (xmldoc) xmldoc->addTextElementToData(safePreferenceName,
"");
2264 void WebUsers::changeSettingsForUser(uint64_t uid,
const std::string &bgcolor,
const std::string &dbcolor,
2265 const std::string &wincolor,
const std::string &layout,
const std::string &syslayout)
2267 uint8_t p = getPermissionsForUser(uid);
2270 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2271 __COUT__ <<
"Changing settings for user: " << UsersUsernameVector[userIndex] << std::endl;
2273 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH + UsersUsernameVector[userIndex] +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2275 __COUT__ <<
"Preferences file: " << fn << std::endl;
2278 prefXml.addTextElementToData(PREF_XML_BGCOLOR_FIELD, bgcolor);
2279 prefXml.addTextElementToData(PREF_XML_DBCOLOR_FIELD, dbcolor);
2280 prefXml.addTextElementToData(PREF_XML_WINCOLOR_FIELD, wincolor);
2281 prefXml.addTextElementToData(PREF_XML_LAYOUT_FIELD, layout);
2283 prefXml.saveXmlDocument(fn);
2286 if (p < 255)
return;
2289 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2290 (std::string)SYSTEM_PREFERENCES_PREFIX +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2293 sysPrefXml.addTextElementToData(PREF_XML_SYSLAYOUT_FIELD, syslayout);
2295 sysPrefXml.saveXmlDocument(fn);
2304 bool WebUsers::setUserWithLock(uint64_t uid_master,
bool lock, std::
string username)
2306 uint8_t p = getPermissionsForUser(uid_master);
2308 __COUT__ <<
"permissions " << (int)p << std::endl;
2309 __COUT__ <<
"usersUsernameWithLock_ " << usersUsernameWithLock_ << std::endl;
2310 __COUT__ <<
"lock " << lock << std::endl;
2311 __COUT__ <<
"username " << username << std::endl;
2312 __COUT__ <<
"isUsernameActive(username) " << isUsernameActive(username) << std::endl;
2314 if (p != (uint8_t)-1)
return false;
2317 if (lock && (isUsernameActive(username) || !CareAboutCookieCodes_))
2319 if (!CareAboutCookieCodes_ && username != DEFAULT_ADMIN_USERNAME)
2321 __COUT__ <<
"User tried to lock for a user other than admin in wiz mode. Not allowed." << std::endl;
2324 usersUsernameWithLock_ = username;
2326 else if (!lock && usersUsernameWithLock_ == username)
2327 usersUsernameWithLock_ =
"";
2330 if (!isUsernameActive(username))
2331 __COUT__ <<
"User is inactive." << std::endl;
2332 __MOUT_WARN__ <<
"Failed to lock for user '" << username <<
".'" << std::endl;
2336 __MOUT_INFO__ <<
"User '" << username <<
"' has locked out the system!" << std::endl;
2340 std::string securityFileName = USER_WITH_LOCK_FILE;
2341 FILE *fp = fopen(securityFileName.c_str(),
"w");
2344 __COUT_INFO__ <<
"USER_WITH_LOCK_FILE " << USER_WITH_LOCK_FILE <<
2345 " not found. Ignoring." << std::endl;
2349 fprintf(fp,
"%s", usersUsernameWithLock_.c_str());
2358 void WebUsers::modifyAccountSettings(uint64_t uid_master, uint8_t cmd_type, std::string username, std::string displayname, std::string email, std::string permissions)
2361 uint8_t p = getPermissionsForUser(uid_master);
2362 if (p != (uint8_t)-1)
return;
2364 uint64_t modi = searchUsersDatabaseForUsername(username);
2367 __COUT__ <<
"Cannot modify first user" << std::endl;
2371 if (username.length() < USERNAME_LENGTH || displayname.length() < DISPLAY_NAME_LENGTH)
2373 __COUT__ <<
"Invalid Username or Display Name must be length " << USERNAME_LENGTH <<
" or " << DISPLAY_NAME_LENGTH << std::endl;
2378 sscanf(permissions.c_str(),
"%d", &inputp);
2380 __COUT__ <<
"Input Permissions " << inputp << std::endl;
2384 case MOD_TYPE_UPDATE:
2385 __COUT__ <<
"MOD_TYPE_UPDATE " << username <<
" := " << inputp << std::endl;
2386 if (modi == NOT_FOUND_IN_DATABASE)
2388 __COUT__ <<
"User not found!? Should not happen." << std::endl;
2392 UsersDisplayNameVector[modi] = displayname;
2393 UsersUserEmailVector[modi] = email;
2397 if (!UsersPermissionsVector[modi] && inputp)
2399 UsersLoginFailureCountVector[modi] = 0;
2400 UsersSaltVector[modi] =
"";
2402 UsersPermissionsVector[modi] = inputp;
2406 uint64_t i = searchUsersDatabaseForUserId(uid_master);
2407 if (i == NOT_FOUND_IN_DATABASE)
2409 __COUT__ <<
"Master User not found!? Should not happen." << std::endl;
2412 UsersLastModifierUsernameVector[modi] = UsersUsernameVector[i];
2413 UsersLastModifiedTimeVector[modi] = time(0);
2417 __COUT__ <<
"MOD_TYPE_ADD " << username <<
" - " << displayname << std::endl;
2418 createNewAccount(username, displayname, email);
2420 case MOD_TYPE_DELETE:
2421 __COUT__ <<
"MOD_TYPE_DELETE " << username <<
" - " << displayname << std::endl;
2422 deleteAccount(username, displayname);
2425 __COUT__ <<
"Undefined command - do nothing " << username << std::endl;
2428 saveDatabaseToFile(DB_USERS);
2433 std::string WebUsers::getActiveUsersString()
2435 std::string ret =
"";
2438 for (uint64_t i = 0; i < ActiveSessionUserIdVector.size(); ++i)
2442 for (uint64_t j = 0; j < i; ++j)
2443 if (ActiveSessionUserIdVector[i] == ActiveSessionUserIdVector[j])
2445 repeat =
true;
break;
2448 if (!repeat && (u = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) !=
2449 NOT_FOUND_IN_DATABASE)
2450 ret += UsersDisplayNameVector[u] +
",";
2452 if (ret.length() > 1) ret.erase(ret.length() - 1);
2458 uint64_t WebUsers::getAdminUserID()
2460 uint64_t uid = searchUsersDatabaseForUsername(DEFAULT_ADMIN_USERNAME);
2468 void WebUsers::loadUserWithLock()
2470 char username[300] =
"";
2472 std::string securityFileName = USER_WITH_LOCK_FILE;
2473 FILE *fp = fopen(securityFileName.c_str(),
"r");
2476 __COUT_INFO__ <<
"USER_WITH_LOCK_FILE " << USER_WITH_LOCK_FILE <<
2477 " not found. Defaulting to admin lock." << std::endl;
2480 sprintf(username,
"%s", DEFAULT_ADMIN_USERNAME.c_str());
2484 fgets(username, 300, fp);
2485 username[299] =
'\0';
2490 __COUT__ <<
"Attempting to load username with lock: " << username << std::endl;
2492 if (strlen(username) == 0)
2494 __COUT_INFO__ <<
"Loaded state for user-with-lock is unlocked." << std::endl;
2498 uint64_t i = searchUsersDatabaseForUsername(username);
2499 if (i == NOT_FOUND_IN_DATABASE)
2501 __COUT_INFO__ <<
"username " << username <<
2502 " not found in database. Ignoring." << std::endl;
2505 __COUT__ <<
"Setting lock" << std::endl;
2506 setUserWithLock(UsersUserIdVector[i],
true, username);
2512 std::string WebUsers::getSecurity()
2514 return securityType_;
2519 void WebUsers::loadSecuritySelection()
2521 std::string securityFileName = SECURITY_FILE_NAME;
2522 FILE *fp = fopen(securityFileName.c_str(),
"r");
2523 char line[100] =
"";
2524 if (fp) fgets(line, 100, fp);
2528 while (i < strlen(line) && line[i] >=
'A' && line[i] <=
'z') ++i;
2532 if (strcmp(line, SECURITY_TYPE_NONE.c_str()) == 0 ||
2533 strcmp(line, SECURITY_TYPE_DIGEST_ACCESS.c_str()) == 0)
2534 securityType_ = line;
2536 securityType_ = SECURITY_TYPE_DIGEST_ACCESS;
2538 __COUT__ <<
"The current security type is " << securityType_ << std::endl;
2543 if (securityType_ == SECURITY_TYPE_NONE)
2544 CareAboutCookieCodes_ =
false;
2546 CareAboutCookieCodes_ =
true;
2548 __COUT__ <<
"CareAboutCookieCodes_: " <<
2549 CareAboutCookieCodes_ << std::endl;
2556 void WebUsers::NACDisplayThread(std::string nac, std::string user)
2558 INIT_MF(
"WebUsers_NAC");
2567 std::this_thread::sleep_for(std::chrono::seconds(2));
2568 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2569 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2570 __COUT__ << __COUT_HDR_P__ <<
"\n\nNew account code = " << nac <<
" for user: " << user <<
"\n" << std::endl;
2571 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2572 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2577 void WebUsers::deleteUserData()
2580 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + HASHES_DB_PATH +
"/*").c_str());
2581 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH +
"/*").c_str());
2582 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + USERS_LOGIN_HISTORY_PATH +
"/*").c_str());
2583 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + USERS_PREFERENCES_PATH +
"/*").c_str());
2584 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH).c_str());
2586 std::string serviceDataPath = getenv(
"SERVICE_DATA_PATH");
2588 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/MacroData/").c_str());
2589 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/MacroHistory/").c_str());
2590 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/MacroExport/").c_str());
2593 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/ConsolePreferences/").c_str());
2596 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/OtsWizardData/").c_str());
2599 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/ProgressBarData/").c_str());
2602 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/RunNumber/").c_str());
2603 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/RunControlData/").c_str());
2606 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/VisualizerData/").c_str());
2609 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/ActiveConfigurationGroups.cfg").c_str());
2612 std::system((
"rm -rf " + std::string(getenv(
"LOGBOOK_DATA_PATH")) +
"/").c_str());
2614 std::cout << __COUT_HDR_FL__ <<
"$$$$$$$$$$$$$$ Successfully deleted ALL service user data $$$$$$$$$$$$" << std::endl;