From: Enzo Matsumiya <ematsumiya@suse.de>
To: linux-cifs@vger.kernel.org, linkinjeon@kernel.org
Cc: senozhatsky@chromium.org, sergey.senozhatsky@gmail.com,
hyc.lee@gmail.com, smfrench@gmail.com,
Enzo Matsumiya <ematsumiya@suse.de>
Subject: [PATCH 5/9] user: introduce user_cmd
Date: Sun, 6 Mar 2022 22:33:40 -0300 [thread overview]
Message-ID: <20220307013344.29064-6-ematsumiya@suse.de> (raw)
In-Reply-To: <20220307013344.29064-1-ematsumiya@suse.de>
Create user command in preparation for binary unification.
Rename some variables to make them more relatable to user properties and
management.
Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
---
daemon/daemon.c | 12 +-
daemon/ipc.c | 6 +-
include/config_parser.h | 2 +-
include/ksmbdtools.h | 7 +-
lib/config_parser.c | 4 +-
user/Makefile.am | 2 +-
user/adduser.c | 180 -----------------------------
user/user.c | 238 ++++++++++++++++++++++++++++++++++++++
user/user_admin.c | 247 +++++++++++++++++++++-------------------
user/user_admin.h | 35 +++++-
10 files changed, 417 insertions(+), 316 deletions(-)
delete mode 100644 user/adduser.c
create mode 100644 user/user.c
diff --git a/daemon/daemon.c b/daemon/daemon.c
index 946f500bc977..50afbd2ed70d 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -291,11 +291,11 @@ static int setup_signals(sighandler_t handler)
return 0;
}
-static int parse_configs(char *pwddb, char *smbconf)
+static int parse_configs(char *db, char *smbconf)
{
int ret;
- ret = cp_parse_pwddb(pwddb);
+ ret = cp_parse_db(db);
if (ret == -ENOENT) {
pr_err("User database file does not exist. %s\n",
"Only guest sessions (if permitted) will work.");
@@ -395,7 +395,7 @@ static int worker_process_init(void)
goto out;
}
- ret = parse_configs(global_conf.pwddb, global_conf.smbconf);
+ ret = parse_configs(global_conf.db, global_conf.smbconf);
if (ret) {
pr_err("Failed to parse configuration files\n");
goto out;
@@ -645,7 +645,7 @@ int main(int argc, char *argv[])
set_logger_app_name("ksmbd.daemon");
memset(&global_conf, 0x00, sizeof(struct smbconf_global));
- global_conf.pwddb = PATH_PWDDB;
+ global_conf.db = PATH_USERS_DB;
global_conf.smbconf = PATH_SMBCONF;
pr_logger_init(PR_LOGGER_STDIO);
@@ -669,7 +669,7 @@ int main(int argc, char *argv[])
global_conf.smbconf = g_strdup(optarg);
break;
case 'u':
- global_conf.pwddb = g_strdup(optarg);
+ global_conf.db = g_strdup(optarg);
break;
case 'n':
if (!optarg)
@@ -694,7 +694,7 @@ int main(int argc, char *argv[])
}
}
- if (!global_conf.smbconf || !global_conf.pwddb) {
+ if (!global_conf.smbconf || !global_conf.db) {
pr_err("Out of memory\n");
exit(EXIT_FAILURE);
}
diff --git a/daemon/ipc.c b/daemon/ipc.c
index c46cbc174175..b793a1e101b0 100644
--- a/daemon/ipc.c
+++ b/daemon/ipc.c
@@ -63,13 +63,13 @@ static int generic_event(int type, void *payload, size_t sz)
return 0;
}
-static int parse_reload_configs(const char *pwddb, const char *smbconf)
+static int parse_reload_configs(const char *db, const char *smbconf)
{
int ret;
pr_debug("Reload config\n");
usm_remove_all_users();
- ret = cp_parse_pwddb(pwddb);
+ ret = cp_parse_db(db);
if (ret == -ENOENT) {
pr_err("User database file does not exist. %s\n",
"Only guest sessions (if permitted) will work.");
@@ -91,7 +91,7 @@ static int handle_generic_event(struct nl_cache_ops *unused,
void *arg)
{
if (ksmbd_health_status & KSMBD_SHOULD_RELOAD_CONFIG) {
- parse_reload_configs(global_conf.pwddb, global_conf.smbconf);
+ parse_reload_configs(global_conf.db, global_conf.smbconf);
ksmbd_health_status &= ~KSMBD_SHOULD_RELOAD_CONFIG;
}
diff --git a/include/config_parser.h b/include/config_parser.h
index c051f487c319..0aefc3b4d5c7 100644
--- a/include/config_parser.h
+++ b/include/config_parser.h
@@ -26,7 +26,7 @@ int cp_parse_external_smbconf_group(char *name, char *opts);
int cp_smbconfig_hash_create(const char *smbconf);
void cp_smbconfig_destroy(void);
-int cp_parse_pwddb(const char *pwddb);
+int cp_parse_db(const char *db);
int cp_parse_smbconf(const char *smbconf);
int cp_parse_reload_smbconf(const char *smbconf);
int cp_parse_subauth(const char *subauth_path);
diff --git a/include/ksmbdtools.h b/include/ksmbdtools.h
index fccb88d8898a..978cbe148eac 100644
--- a/include/ksmbdtools.h
+++ b/include/ksmbdtools.h
@@ -57,7 +57,7 @@ struct smbconf_global {
unsigned int gen_subauth[3];
char *krb5_keytab_file;
char *krb5_service_name;
- char *pwddb;
+ char *db;
char *smbconf;
};
@@ -85,8 +85,9 @@ extern struct smbconf_global global_conf;
#define KSMBD_CONF_FILE_MAX 10000
-#define PATH_PWDDB "/etc/ksmbd/ksmbdpwd.db"
-#define PATH_SMBCONF "/etc/ksmbd/smb.conf"
+#define PATH_USERS_DB "/etc/ksmbd/users.db"
+#define PATH_OLD_USERS_DB "/etc/ksmbd/ksmbdpwd.db"
+#define PATH_SMBCONF "/etc/ksmbd/smb.conf"
#define KSMBD_HEALTH_START (0)
#define KSMBD_HEALTH_RUNNING (1 << 0)
diff --git a/lib/config_parser.c b/lib/config_parser.c
index 20e27c3ab8ec..a000a2a6059e 100644
--- a/lib/config_parser.c
+++ b/lib/config_parser.c
@@ -680,9 +680,9 @@ int cp_parse_smbconf(const char *smbconf)
GROUPS_CALLBACK_STARTUP_INIT);
}
-int cp_parse_pwddb(const char *pwddb)
+int cp_parse_db(const char *db)
{
- return __mmap_parse_file(pwddb, usm_add_update_user_from_pwdentry);
+ return __mmap_parse_file(db, usm_add_update_user_from_pwdentry);
}
int cp_smbconfig_hash_create(const char *smbconf)
diff --git a/user/Makefile.am b/user/Makefile.am
index c5cee686f5cc..ba491c84f0f4 100644
--- a/user/Makefile.am
+++ b/user/Makefile.am
@@ -4,4 +4,4 @@ ksmbd_adduser_LDADD = $(top_builddir)/lib/libksmbdtools.a
sbin_PROGRAMS = ksmbd.adduser
-ksmbd_adduser_SOURCES = md4_hash.c user_admin.c adduser.c md4_hash.h user_admin.h
+ksmbd_adduser_SOURCES = md4_hash.c user_admin.c user.c md4_hash.h user_admin.h
diff --git a/user/adduser.c b/user/adduser.c
deleted file mode 100644
index 88b12db9f439..000000000000
--- a/user/adduser.c
+++ /dev/null
@@ -1,180 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2018 Samsung Electronics Co., Ltd.
- *
- * linux-cifsd-devel@lists.sourceforge.net
- */
-
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "config_parser.h"
-#include "ksmbdtools.h"
-#include "management/user.h"
-#include "management/share.h"
-#include "user_admin.h"
-#include "linux/ksmbd_server.h"
-#include "version.h"
-
-static char *arg_account = NULL;
-static char *arg_password = NULL;
-
-enum {
- COMMAND_ADD_USER = 1,
- COMMAND_DEL_USER,
- COMMAND_UPDATE_USER,
-};
-
-static void usage(void)
-{
- fprintf(stderr, "Usage: smbuseradd\n");
-
- fprintf(stderr, "\t-a | --add-user=login\n");
- fprintf(stderr, "\t-d | --del-user=login\n");
- fprintf(stderr, "\t-u | --update-user=login\n");
- fprintf(stderr, "\t-p | --password=pass\n");
-
- fprintf(stderr, "\t-i smbpwd.db | --import-users=smbpwd.db\n");
- fprintf(stderr, "\t-V | --version\n");
- fprintf(stderr, "\t-v | --verbose\n");
-
- exit(EXIT_FAILURE);
-}
-
-static void show_version(void)
-{
- printf("ksmbd-tools version : %s\n", KSMBD_TOOLS_VERSION);
- exit(EXIT_FAILURE);
-}
-
-static int parse_configs(char *pwddb)
-{
- int ret;
-
- ret = test_file_access(pwddb);
- if (ret)
- return ret;
-
- ret = cp_parse_pwddb(pwddb);
- if (ret)
- return ret;
- return 0;
-}
-
-static int sanity_check_user_name_simple(char *uname)
-{
- int sz, i;
-
- if (!uname)
- return -EINVAL;
-
- sz = strlen(uname);
- if (sz < 1)
- return -EINVAL;
- if (sz >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
- return -EINVAL;
-
- /* 1'; Drop table users -- */
- if (!strcmp(uname, "root"))
- return -EINVAL;
-
- if (strpbrk(uname, ":\n"))
- return -EINVAL;
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int ret = EXIT_FAILURE;
- char *pwddb = PATH_PWDDB;
- int c, cmd = 0;
-
- set_logger_app_name("ksmbd.adduser");
-
- opterr = 0;
- while ((c = getopt(argc, argv, "c:i:a:d:u:p:Vvh")) != EOF)
- switch (c) {
- case 'a':
- arg_account = g_strdup(optarg);
- cmd = COMMAND_ADD_USER;
- break;
- case 'd':
- arg_account = g_strdup(optarg);
- cmd = COMMAND_DEL_USER;
- break;
- case 'u':
- arg_account = g_strdup(optarg);
- cmd = COMMAND_UPDATE_USER;
- break;
- case 'p':
- arg_password = g_strdup(optarg);
- break;
- case 'i':
- pwddb = g_strdup(optarg);
- break;
- case 'V':
- show_version();
- break;
- case 'v':
- break;
- case '?':
- case 'h':
- default:
- usage();
- }
-
- if (sanity_check_user_name_simple(arg_account)) {
- pr_err("User name sanity check failure\n");
- goto out;
- }
-
- if (!pwddb) {
- pr_err("Out of memory\n");
- goto out;
- }
-
- ret = usm_init();
- if (ret) {
- pr_err("Failed to init user management\n");
- goto out;
- }
-
- ret = shm_init();
- if (ret) {
- pr_err("Failed to init net share management\n");
- goto out;
- }
-
- ret = parse_configs(pwddb);
- if (ret) {
- pr_err("Unable to parse configuration files\n");
- goto out;
- }
-
- if (cmd == COMMAND_ADD_USER)
- ret = command_add_user(pwddb, arg_account, arg_password);
- if (cmd == COMMAND_DEL_USER)
- ret = command_del_user(pwddb, arg_account);
- if (cmd == COMMAND_UPDATE_USER)
- ret = command_update_user(pwddb, arg_account, arg_password);
-
- /*
- * We support only ADD_USER command at this moment
- */
- if (ret == 0 && cmd == COMMAND_ADD_USER)
- notify_ksmbd_daemon();
-out:
- shm_destroy();
- usm_destroy();
- return ret;
-}
diff --git a/user/user.c b/user/user.c
new file mode 100644
index 000000000000..f59c34c11b02
--- /dev/null
+++ b/user/user.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 SUSE LLC
+ *
+ * linux-cifsd-devel@lists.sourceforge.net
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "config_parser.h"
+#include "ksmbdtools.h"
+#include "management/user.h"
+#include "management/share.h"
+#include "user_admin.h"
+#include "linux/ksmbd_server.h"
+
+static ksmbd_user_cmd ksmbd_user_get_cmd(char *cmd)
+{
+ int i;
+
+ if (!cmd)
+ return KSMBD_CMD_USER_NONE;
+
+ for (i = 1; i < KSMBD_CMD_USER_MAX; i++)
+ if (!strcmp(cmd, ksmbd_user_cmds_str[i]))
+ return (ksmbd_user_cmd)i;
+
+ return KSMBD_CMD_USER_NONE;
+}
+
+static const char *ksmbd_user_get_cmd_str(ksmbd_user_cmd cmd)
+{
+ if (cmd > KSMBD_CMD_USER_MAX)
+ return ksmbd_user_cmds_str[KSMBD_CMD_USER_NONE];
+
+ return ksmbd_user_cmds_str[(int)cmd];
+}
+
+void user_usage(ksmbd_user_cmd cmd)
+{
+ const char *cmd_str = ksmbd_user_get_cmd_str(cmd);
+
+ switch (cmd) {
+ case KSMBD_CMD_USER_ADD:
+ case KSMBD_CMD_USER_UPDATE:
+ pr_out("Usage: ksmbdctl user %s <username> [-p <password>] [-d <file>]\n", cmd_str);
+ pr_out("Adds or updates a user to the database.\n\n");
+ pr_out("%-30s%s", " -p, --password=<password>", "Use <password> for <username>\n");
+ pr_out("%-30s%s", " -d, --database=<file>", "Use <file> as database\n\n");
+ break;
+ case KSMBD_CMD_USER_DELETE:
+ pr_out("Usage: ksmbdctl user delete <username>\n");
+ pr_out("Delete user from database.\n\n");
+ break;
+ case KSMBD_CMD_USER_LIST:
+ pr_out("Usage: ksmbdctl user list\n");
+ pr_out("List users in database.\n\n");
+ pr_out("%-30s%s", " -d, --database=<file>", "Use <file> as database\n\n");
+ break;
+ default:
+ pr_out("Usage: ksmbdctl user <subcommand> <args> [options]\n");
+ pr_out("User management.\n\n");
+ pr_out("List of available subcommands:\n");
+ pr_out("%-20s%s", " add", "Add a user\n");
+ pr_out("%-20s%s", " delete", "Delete a user\n");
+ pr_out("%-20s%s", " update", "Update an existing user\n");
+ pr_out("%-20s%s", " list", "List users in user database\n\n");
+ break;
+ }
+
+ exit(EXIT_FAILURE);
+}
+
+static int parse_configs(char *db)
+{
+ int ret;
+
+ ret = test_file_access(db);
+ if (ret)
+ return ret;
+
+ ret = cp_parse_db(db);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+static int sanity_check_user_name_simple(char *uname)
+{
+ int sz, i;
+
+ if (!uname)
+ return -EINVAL;
+
+ sz = strlen(uname);
+ if (sz < 1)
+ return -EINVAL;
+ if (sz >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
+ return -EINVAL;
+
+ /* 1'; Drop table users -- */
+ if (!strcmp(uname, "root"))
+ return -EINVAL;
+
+ for (i = 0; i < sz; i++) {
+ if (isalnum(uname[i]))
+ return 0;
+ }
+ return -EINVAL;
+}
+
+int user_cmd(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+ char *db = PATH_USERS_DB;
+ char *login = NULL;
+ char *pw = NULL;
+ ksmbd_user_cmd cmd = KSMBD_CMD_USER_NONE;
+ const char *cmd_str = NULL;
+ int c;
+
+ if (argc < 2)
+ goto usage;
+
+ set_logger_app_name("ksmbd-user");
+
+ cmd = ksmbd_user_get_cmd(argv[1]);
+ cmd_str = ksmbd_user_get_cmd_str(cmd);
+
+ if (cmd == KSMBD_CMD_USER_NONE)
+ goto usage;
+
+ if (cmd != KSMBD_CMD_USER_LIST) {
+ if (argc == 2)
+ goto missing_arg;
+
+ if (argv[2][0] != '-')
+ login = g_strdup(argv[2]);
+ else
+ goto usage;
+ }
+
+ optind = 1;
+ while((c = getopt_long(argc, argv, "-:p:d:", user_opts, NULL)) != EOF)
+ switch (c) {
+ case 1:
+ break;
+ case 'p':
+ pw = g_strdup(optarg);
+ break;
+ case 'd':
+ db = g_strdup(optarg);
+ break;
+ case ':':
+ case '?':
+ default:
+ goto usage;
+ }
+
+ if (cmd == KSMBD_CMD_USER_LIST)
+ goto user_list;
+
+ if (!login)
+ goto missing_arg;
+
+ if (sanity_check_user_name_simple(login)) {
+ pr_err("User name (%s) sanity check failure\n");
+ goto out;
+ }
+
+user_list:
+ if (!db) {
+ pr_err("Out of memory\n");
+ goto out;
+ }
+
+ ret = usm_init();
+ if (ret) {
+ pr_err("Failed to init user management\n");
+ goto out;
+ }
+
+ ret = shm_init();
+ if (ret) {
+ pr_err("Failed to init net share management\n");
+ goto out;
+ }
+
+ ret = parse_configs(db);
+ if (ret) {
+ pr_err("Unable to parse database file %s\n", db);
+ goto out;
+ }
+
+ switch (cmd) {
+ case KSMBD_CMD_USER_ADD:
+ ret = user_add_cmd(db, login, pw);
+ break;
+ case KSMBD_CMD_USER_DELETE:
+ ret = user_delete_cmd(db, login);
+ break;
+ case KSMBD_CMD_USER_UPDATE:
+ ret = user_update_cmd(db, login, pw);
+ break;
+ case KSMBD_CMD_USER_LIST:
+ ret = user_list_cmd(db);
+ break;
+ }
+
+ /*
+ * FIXME: We support only ADD_USER command at this moment
+ */
+ if (ret == 0 && cmd == KSMBD_CMD_USER_ADD)
+ notify_ksmbd_daemon();
+out:
+ shm_destroy();
+ usm_destroy();
+ return ret;
+
+missing_arg:
+ if (cmd > KSMBD_CMD_USER_NONE && cmd < KSMBD_CMD_USER_MAX)
+ pr_out("Subcommand \"%s\" requires an argument.\n\n", cmd_str);
+usage:
+ user_usage(cmd);
+
+ return ret;
+}
diff --git a/user/user_admin.c b/user/user_admin.c
index 95b05ea33f28..ca0e14978701 100644
--- a/user/user_admin.c
+++ b/user/user_admin.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 SUSE LLC
*
* linux-cifsd-devel@lists.sourceforge.net
*/
@@ -8,8 +9,8 @@
#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stdbool.h>
#include <unistd.h>
-#include <getopt.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
@@ -24,23 +25,23 @@
#define MAX_NT_PWD_LEN 129
-static char *arg_account = NULL;
-static char *arg_password = NULL;
static int conf_fd = -1;
static char wbuf[2 * MAX_NT_PWD_LEN + 2 * KSMBD_REQ_MAX_ACCOUNT_NAME_SZ];
-static int __opendb_file(char *pwddb)
+static int open_db(char *db, bool truncate)
{
- conf_fd = open(pwddb, O_WRONLY);
+ conf_fd = open(db, O_WRONLY);
if (conf_fd == -1) {
- pr_err("%s %s\n", strerr(errno), pwddb);
+ pr_err("%s %s\n", strerr(errno), db);
return -EINVAL;
}
- if (ftruncate(conf_fd, 0)) {
- pr_err("%s %s\n", strerr(errno), pwddb);
- close(conf_fd);
- return -EINVAL;
+ if (truncate) {
+ if (ftruncate(conf_fd, 0)) {
+ pr_err("%s %s\n", strerr(errno), db);
+ close(conf_fd);
+ return -EINVAL;
+ }
}
return 0;
@@ -60,149 +61,147 @@ static void term_toggle_echo(int on_off)
tcsetattr(STDIN_FILENO, TCSAFLUSH, &term);
}
-static char *__prompt_password_stdin(size_t *sz)
+static char *prompt_password_stdin(size_t *sz)
{
- char *pswd1 = calloc(1, MAX_NT_PWD_LEN + 1);
- char *pswd2 = calloc(1, MAX_NT_PWD_LEN + 1);
+ char *pw1 = calloc(1, MAX_NT_PWD_LEN + 1);
+ char *pw2 = calloc(1, MAX_NT_PWD_LEN + 1);
size_t len = 0;
int i;
- if (!pswd1 || !pswd2) {
- free(pswd1);
- free(pswd2);
- pr_err("Out of memory\n");
- return NULL;
- }
+ if (!pw1 || !pw2)
+ goto fail;
again:
- printf("New password: ");
+ pr_out("New password: ");
term_toggle_echo(0);
- if (fgets(pswd1, MAX_NT_PWD_LEN, stdin) == NULL) {
+ if (fgets(pw1, MAX_NT_PWD_LEN, stdin) == NULL) {
term_toggle_echo(1);
- pr_err("\nFatal error: %s\n", strerr(errno));
- free(pswd1);
- free(pswd2);
- return NULL;
+ pr_out("\n");
+ goto fail;
}
+ pr_out("\n");
- printf("\nRetype new password: ");
- if (fgets(pswd2, MAX_NT_PWD_LEN, stdin) == NULL) {
+ pr_out("Retype new password: ");
+ if (fgets(pw2, MAX_NT_PWD_LEN, stdin) == NULL) {
term_toggle_echo(1);
- pr_err("\nFatal error: %s\n", strerr(errno));
- free(pswd1);
- free(pswd2);
- return NULL;
+ pr_out("\n");
+ goto fail;
}
term_toggle_echo(1);
- printf("\n");
+ pr_out("\n");
- len = strlen(pswd1);
+ len = strlen(pw1);
for (i = 0; i < len; i++)
- if (pswd1[i] == '\n')
- pswd1[i] = 0x00;
+ if (pw1[i] == '\n')
+ pw1[i] = 0x00;
- len = strlen(pswd2);
+ len = strlen(pw2);
for (i = 0; i < len; i++)
- if (pswd2[i] == '\n')
- pswd2[i] = 0x00;
+ if (pw2[i] == '\n')
+ pw2[i] = 0x00;
- if (memcmp(pswd1, pswd2, MAX_NT_PWD_LEN + 1)) {
+ if (memcmp(pw1, pw2, MAX_NT_PWD_LEN + 1)) {
pr_err("Passwords don't match\n");
goto again;
}
- len = strlen(pswd1);
+ len = strlen(pw1);
if (len <= 1) {
pr_err("No password was provided\n");
goto again;
}
*sz = len;
- free(pswd2);
- return pswd1;
+ free(pw2);
+ return pw1;
+fail:
+ pr_err("Fatal error: %s\n", strerr(errno));
+ free(pw1);
+ free(pw2);
+ return NULL;
}
-static char *prompt_password(size_t *sz)
+static char *prompt_password(char *password, size_t *len)
{
- if (!arg_password)
- return __prompt_password_stdin(sz);
+ if (!password)
+ return prompt_password_stdin(len);
- *sz = strlen(arg_password);
- return arg_password;
+ *len = strlen(password);
+ return password;
}
-static char *get_utf8_password(long *len)
+static char *get_utf8_password(char *password, long *len)
{
size_t raw_sz;
- char *pswd_raw, *pswd_converted;
+ char *pw_raw, *pw_converted;
gsize bytes_read = 0;
gsize bytes_written = 0;
- pswd_raw = prompt_password(&raw_sz);
- if (!pswd_raw)
+ pw_raw = prompt_password(password, &raw_sz);
+ if (!pw_raw)
return NULL;
- pswd_converted = ksmbd_gconvert(pswd_raw,
+ pw_converted = ksmbd_gconvert(pw_raw,
raw_sz,
KSMBD_CHARSET_UTF16LE,
KSMBD_CHARSET_DEFAULT,
&bytes_read,
&bytes_written);
- if (!pswd_converted) {
- free(pswd_raw);
+ if (!pw_converted) {
+ free(pw_raw);
return NULL;
}
*len = bytes_written;
- free(pswd_raw);
- return pswd_converted;
+ free(pw_raw);
+ return pw_converted;
}
-static void __sanity_check(char *pswd_hash, char *pswd_b64)
+static void sanity_check_pw(char *pw_hash, char *pw_b64)
{
- size_t pass_sz;
- char *pass = base64_decode(pswd_b64, &pass_sz);
+ size_t len;
+ char *pass = base64_decode(pw_b64, &len);
if (!pass) {
pr_err("Unable to decode NT hash\n");
exit(EXIT_FAILURE);
}
- if (memcmp(pass, pswd_hash, pass_sz)) {
+ if (memcmp(pass, pw_hash, len)) {
pr_err("NT hash encoding error\n");
exit(EXIT_FAILURE);
}
free(pass);
}
-static char *get_hashed_b64_password(void)
+static char *get_hashed_b64_password(char *password)
{
struct md4_ctx mctx;
long len;
- char *pswd_plain, *pswd_hash, *pswd_b64;
+ char *pw_plain, *pw_hash, *pw_b64;
- pswd_plain = get_utf8_password(&len);
- if (!pswd_plain)
+ pw_plain = get_utf8_password(password, &len);
+ if (!pw_plain)
return NULL;
- pswd_hash = calloc(1, sizeof(mctx.hash) + 1);
- if (!pswd_hash) {
- free(pswd_plain);
+ pw_hash = calloc(1, sizeof(mctx.hash) + 1);
+ if (!pw_hash) {
+ free(pw_plain);
pr_err("Out of memory\n");
return NULL;
}
md4_init(&mctx);
- md4_update(&mctx, pswd_plain, len);
- md4_final(&mctx, pswd_hash);
+ md4_update(&mctx, pw_plain, len);
+ md4_final(&mctx, pw_hash);
- pswd_b64 = base64_encode(pswd_hash,
+ pw_b64 = base64_encode(pw_hash,
MD4_HASH_WORDS * sizeof(unsigned int));
- __sanity_check(pswd_hash, pswd_b64);
- free(pswd_plain);
- free(pswd_hash);
- return pswd_b64;
+ sanity_check_pw(pw_hash, pw_b64);
+ free(pw_plain);
+ free(pw_hash);
+ return pw_b64;
}
static void write_user(struct ksmbd_user *user)
@@ -248,7 +247,7 @@ static void write_remove_user_cb(gpointer key,
{
struct ksmbd_user *user = (struct ksmbd_user *)value;
- if (!g_ascii_strcasecmp(user->name, arg_account)) {
+ if (!g_ascii_strcasecmp(user->name, (char *)user_data)) {
pr_info("User '%s' removed\n", user->name);
return;
}
@@ -262,96 +261,91 @@ static void lookup_can_del_user(gpointer key,
{
struct ksmbd_share *share = (struct ksmbd_share *)value;
int ret = 0;
- int *abort_del_user = (int *)user_data;
+ char *account = (char *)user_data;
- if (*abort_del_user)
+ if (!account)
return;
ret = shm_lookup_users_map(share,
KSMBD_SHARE_ADMIN_USERS_MAP,
- arg_account);
+ account);
if (ret == 0)
goto conflict;
ret = shm_lookup_users_map(share,
KSMBD_SHARE_WRITE_LIST_MAP,
- arg_account);
+ account);
if (ret == 0)
goto conflict;
ret = shm_lookup_users_map(share,
KSMBD_SHARE_VALID_USERS_MAP,
- arg_account);
+ account);
if (ret == 0)
goto conflict;
- *abort_del_user = 0;
return;
conflict:
pr_err("Share %s requires user %s to exist\n",
- share->name, arg_account);
- *abort_del_user = 1;
+ share->name, account);
+ account = NULL;
}
-int command_add_user(char *pwddb, char *account, char *password)
+int user_add_cmd(char *db, char *account, char *password)
{
struct ksmbd_user *user;
- char *pswd;
-
- arg_account = account;
- arg_password = password;
+ char *pw;
- user = usm_lookup_user(arg_account);
+ user = usm_lookup_user(account);
if (user) {
put_ksmbd_user(user);
- pr_err("Account `%s' already exists\n", arg_account);
+ pr_err("Account `%s' already exists\n", account);
return -EEXIST;
}
- pswd = get_hashed_b64_password();
- if (!pswd) {
+ pw = get_hashed_b64_password(password);
+ if (!pw) {
pr_err("Out of memory\n");
return -EINVAL;
}
- /* pswd is already g_strdup-ed */
- if (usm_add_new_user(arg_account, pswd)) {
+ /* pw is already g_strdup-ed */
+ if (usm_add_new_user(account, pw)) {
pr_err("Could not add new account\n");
return -EINVAL;
}
- pr_info("User '%s' added\n", arg_account);
- if (__opendb_file(pwddb))
+ if (open_db(db, true))
return -EINVAL;
for_each_ksmbd_user(write_user_cb, NULL);
+
+ pr_info("User '%s' added\n", account);
+
close(conf_fd);
return 0;
}
-int command_update_user(char *pwddb, char *account, char *password)
+int user_update_cmd(char *db, char *account, char *password)
{
struct ksmbd_user *user;
- char *pswd;
-
- arg_password = password;
- arg_account = account;
+ char *pw;
- user = usm_lookup_user(arg_account);
+ user = usm_lookup_user(account);
if (!user) {
- pr_err("Unknown account\n");
+ pr_err("Unknown account \"%s\"\n", account);
return -EINVAL;
}
- pswd = get_hashed_b64_password();
- if (!pswd) {
+ pw = get_hashed_b64_password(password);
+ if (!pw) {
pr_err("Out of memory\n");
put_ksmbd_user(user);
return -EINVAL;
}
- if (usm_update_user_password(user, pswd)) {
+ if (usm_update_user_password(user, pw)) {
pr_err("Out of memory\n");
put_ksmbd_user(user);
return -ENOMEM;
@@ -359,9 +353,9 @@ int command_update_user(char *pwddb, char *account, char *password)
pr_info("User '%s' updated\n", account);
put_ksmbd_user(user);
- free(pswd);
+ free(pw);
- if (__opendb_file(pwddb))
+ if (open_db(db, true))
return -EINVAL;
for_each_ksmbd_user(write_user_cb, NULL);
@@ -369,28 +363,47 @@ int command_update_user(char *pwddb, char *account, char *password)
return 0;
}
-int command_del_user(char *pwddb, char *account)
+int user_delete_cmd(char *db, char *account)
{
- int abort_del_user = 0;
+ char *abort_del_user = strdup(account);
- arg_account = account;
- if (!cp_key_cmp(global_conf.guest_account, arg_account)) {
+ if (!cp_key_cmp(global_conf.guest_account, account)) {
pr_err("User %s is a global guest account. Abort deletion.\n",
- arg_account);
+ account);
return -EINVAL;
}
- for_each_ksmbd_share(lookup_can_del_user, &abort_del_user);
+ for_each_ksmbd_share(lookup_can_del_user, abort_del_user);
- if (abort_del_user) {
+ if (!abort_del_user) {
pr_err("Aborting user deletion\n");
return -EINVAL;
}
- if (__opendb_file(pwddb))
+ if (open_db(db, true))
+ return -EINVAL;
+
+ for_each_ksmbd_user(write_remove_user_cb, account);
+ close(conf_fd);
+ return 0;
+}
+
+static void list_users_cb(gpointer key, gpointer value, gpointer data)
+{
+ struct ksmbd_user *user = (struct ksmbd_user *)value;
+
+ pr_out("%s\n", user->name);
+}
+
+int user_list_cmd(char *db)
+{
+ if (open_db(db, false))
return -EINVAL;
- for_each_ksmbd_user(write_remove_user_cb, NULL);
+ pr_out("Users in %s:\n", db);
+ for_each_ksmbd_user(list_users_cb, NULL);
+ pr_out("\n");
close(conf_fd);
+
return 0;
}
diff --git a/user/user_admin.h b/user/user_admin.h
index 9ff839e846bd..2dfbaa00b6b0 100644
--- a/user/user_admin.h
+++ b/user/user_admin.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 SUSE LLC
*
* linux-cifsd-devel@lists.sourceforge.net
*/
@@ -8,8 +9,36 @@
#ifndef __KSMBD_USER_ADMIN_H__
#define __KSMBD_USER_ADMIN_H__
-int command_add_user(char *pwddb, char *account, char *password);
-int command_update_user(char *pwddb, char *account, char *password);
-int command_del_user(char *pwddb, char *account);
+int user_add_cmd(char *db, char *account, char *password);
+int user_delete_cmd(char *db, char *account);
+int user_update_cmd(char *db, char *account, char *password);
+int user_list_cmd(char *db);
+
+typedef enum {
+ KSMBD_CMD_USER_NONE = 0,
+ KSMBD_CMD_USER_ADD,
+ KSMBD_CMD_USER_DELETE,
+ KSMBD_CMD_USER_UPDATE,
+ KSMBD_CMD_USER_LIST,
+ KSMBD_CMD_USER_MAX
+} ksmbd_user_cmd;
+
+/* List of supported subcommands */
+static const char *ksmbd_user_cmds_str[] = {
+ "none",
+ "add",
+ "delete",
+ "update",
+ "list",
+};
+
+static struct option user_opts[] = {
+ { "password", required_argument, NULL, 'p' },
+ { "database", required_argument, NULL, 'd' },
+ { 0, 0, 0, 0 },
+};
+
+void user_usage(ksmbd_user_cmd cmd);
+int user_cmd(int argc, char *argv[]);
#endif /* __KSMBD_USER_ADMIN_H__ */
--
2.34.1
next prev parent reply other threads:[~2022-03-07 1:34 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-07 1:33 [PATCH 0/9] Unify all programs into a single binary "ksmbdctl" Enzo Matsumiya
2022-03-07 1:33 ` [PATCH 1/9] ksmbd-tools: rename dirs to reflect new commands Enzo Matsumiya
2022-03-07 1:33 ` [PATCH 2/9] ksmbd-tools: move control functions to daemon Enzo Matsumiya
2022-03-07 1:33 ` [PATCH 3/9] ksmbd-tools: use quotes for local includes Enzo Matsumiya
2022-03-07 1:33 ` [PATCH 4/9] share: introduce share_cmd Enzo Matsumiya
2022-03-10 2:19 ` Namjae Jeon
2022-03-07 1:33 ` Enzo Matsumiya [this message]
2022-03-10 2:17 ` [PATCH 5/9] user: introduce user_cmd Namjae Jeon
2022-03-07 1:33 ` [PATCH 6/9] daemon: introduce daemon_cmd Enzo Matsumiya
2022-03-07 1:33 ` [PATCH 7/9] daemon/rpc_samr: drop unused function rpc_samr_remove_domain_entry() Enzo Matsumiya
2022-03-07 1:33 ` [PATCH 8/9] Unify all programs into a single binary "ksmbdctl" Enzo Matsumiya
2022-03-07 1:33 ` [PATCH 9/9] README: change to markdown, updates for ksmbdctl Enzo Matsumiya
2022-03-10 2:11 ` [PATCH 0/9] Unify all programs into a single binary "ksmbdctl" Namjae Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220307013344.29064-6-ematsumiya@suse.de \
--to=ematsumiya@suse.de \
--cc=hyc.lee@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=senozhatsky@chromium.org \
--cc=sergey.senozhatsky@gmail.com \
--cc=smfrench@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox