diff --git a/commands/password.c b/commands/password.c
new file mode 100644
index 0000000..0c0cd6c
--- /dev/null
+++ b/commands/password.c
@@ -0,0 +1,84 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static grub_dl_t my_mod;
+
+static grub_err_t
+check_password (const char *user,
+ void *password)
+{
+ char entered[1024] = {0};
+
+ if (!GRUB_GET_PASSWORD (entered, sizeof (entered) - 1))
+ return GRUB_ACCESS_DENIED;
+
+ if (grub_auth_strcmp (entered, password) != 0)
+ return GRUB_ACCESS_DENIED;
+
+ grub_auth_authenticate (user);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_err_t err;
+ char *pass;
+
+ if (argc != 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
+
+ pass = grub_strdup (args[1]);
+ if (!pass)
+ return grub_errno;
+
+ err = grub_auth_register_authentication (args[0], check_password, pass);
+ if (err)
+ {
+ grub_free (pass);
+ return err;
+ }
+ grub_dl_ref (my_mod);
+ return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(password)
+{
+ my_mod = mod;
+ cmd = grub_register_command ("password", grub_cmd_password,
+ "password USER PASSWORD",
+ "Set user password (plaintext). "
+ "Unrecommended and insecure.");
+}
+
+GRUB_MOD_FINI(password)
+{
+ grub_unregister_command (cmd);
+}
diff --git a/conf/common.rmk b/conf/common.rmk
index b0d3785..db7fa1a 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -364,7 +364,12 @@ pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
read.mod sleep.mod loadenv.mod crc.mod parttool.mod \
pcpart.mod memrw.mod normal.mod sh.mod lua.mod \
- gptsync.mod true.mod probe.mod
+ gptsync.mod true.mod probe.mod password.mod
+
+# For password.mod.
+password_mod_SOURCES = commands/password.c
+password_mod_CFLAGS = $(COMMON_CFLAGS)
+password_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For gptsync.mod.
gptsync_mod_SOURCES = commands/gptsync.c
@@ -508,7 +513,7 @@ probe_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For normal.mod.
normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
- normal/autofs.c normal/handler.c \
+ normal/auth.c normal/autofs.c normal/handler.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
normal/misc.c
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index ce2576b..74f8217 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -110,6 +110,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
+ commands/password.c \
lib/hexdump.c commands/i386/cpuid.c \
disk/host.c disk/loopback.c \
\
@@ -127,7 +128,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/partition.c kern/reader.c kern/term.c \
kern/rescue_reader.c kern/rescue_parser.c \
lib/arg.c normal/cmdline.c normal/misc.c \
- normal/handler.c normal/autofs.c \
+ normal/handler.c normal/auth.c normal/autofs.c \
normal/completion.c normal/datetime.c normal/main.c \
normal/menu_text.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index 6e3cbcf..9b8819f 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -39,6 +39,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
+ commands/password.c \
disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
@@ -54,7 +55,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/partition.c kern/reader.c kern/term.c \
kern/rescue_reader.c kern/rescue_parser.c \
lib/arg.c normal/cmdline.c normal/command.c normal/datetime.c \
- normal/autofs.c \
+ normal/auth.c normal/autofs.c \
normal/completion.c normal/context.c normal/main.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
normal/menu_text.c \
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 65d1c6b..7858df7 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -66,6 +66,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
commands/i386/cpuid.c \
+ commands/password.c \
disk/host.c disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
@@ -82,7 +83,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/partition.c kern/reader.c kern/term.c \
kern/rescue_reader.c kern/rescue_parser.c \
lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c \
- normal/handler.c normal/autofs.c \
+ normal/handler.c normal/auth.c normal/autofs.c \
normal/completion.c normal/main.c normal/menu_text.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
normal/color.c \
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 0ef5e47..2655772 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -123,6 +123,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
commands/i386/cpuid.c \
+ commands/password.c \
disk/host.c disk/loopback.c disk/scsi.c \
fs/fshelp.c \
\
@@ -134,7 +135,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/partition.c kern/reader.c kern/term.c \
kern/rescue_reader.c kern/rescue_parser.c \
lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c \
- normal/handler.c normal/autofs.c \
+ normal/handler.c normal/auth.c normal/autofs.c \
normal/completion.c normal/main.c normal/color.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
normal/menu_text.c \
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index c30f61a..10935cb 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -46,6 +46,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
+ commands/password.c \
disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
@@ -62,7 +63,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/command.c kern/corecmd.c commands/extcmd.c \
lib/arg.c normal/cmdline.c normal/datetime.c \
normal/completion.c normal/misc.c \
- normal/handler.c normal/autofs.c normal/main.c \
+ normal/handler.c normal/auth.c normal/autofs.c normal/main.c \
normal/menu.c \
normal/menu_text.c \
normal/menu_entry.c normal/menu_viewer.c \
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index b26496d..c90f305 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -103,6 +103,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
+ commands/password.c \
disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
@@ -119,7 +120,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/command.c kern/corecmd.c commands/extcmd.c \
lib/arg.c normal/cmdline.c normal/datetime.c \
normal/completion.c normal/misc.c \
- normal/handler.c normal/autofs.c normal/main.c \
+ normal/handler.c normal/auth.c normal/autofs.c normal/main.c \
normal/menu.c \
normal/menu_text.c \
normal/menu_entry.c normal/menu_viewer.c \
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
index 71a90ce..1fd9407 100644
--- a/conf/x86_64-efi.rmk
+++ b/conf/x86_64-efi.rmk
@@ -37,6 +37,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
+ commands/password.c \
disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
@@ -50,7 +51,8 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c \
kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \
kern/partition.c kern/readerescue.c kern/term.c \
- lib/arg.c normal/cmdline.c normal/misc.c normal/autofs.c \
+ lib/arg.c normal/cmdline.c normal/misc.c normal/auth.c \
+ normal/autofs.c \
normal/completion.c normal/datetime.c normal/context.c \
normal/main.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
diff --git a/include/grub/auth.h b/include/grub/auth.h
new file mode 100644
index 0000000..da930ee
--- /dev/null
+++ b/include/grub/auth.h
@@ -0,0 +1,45 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+#ifndef GRUB_AURH_HEADER
+#define GRUB_AUTH_HEADER 1
+
+#include
+
+/* Macros for indistinguishibility. */
+#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
+#define GRUB_GET_PASSWORD(string, len) grub_cmdline_get ("Enter password: ", \
+ string, len, \
+ '*', 0, 0)
+
+/* Like strcmp but untimeable. Accepts NULL as second argument. */
+int grub_auth_strcmp (const char *user_input, const char *template);
+/* Like strcmp but untimeable and ignores commas in needle. */
+int grub_auth_strword (const char *haystack, const char *needle);
+
+typedef grub_err_t (*grub_auth_callback_t) (const char*, void *);
+
+grub_err_t grub_auth_register_authentication (const char *user,
+ grub_auth_callback_t callback,
+ void *arg);
+grub_err_t grub_auth_unregister_authentication (const char *user);
+
+grub_err_t grub_auth_authenticate (const char *user);
+grub_err_t grub_auth_deauthenticate (const char *user);
+grub_err_t grub_auth_check_authentication (const char *userlist);
+
+#endif /* ! GRUB_AUTH_HEADER */
diff --git a/include/grub/err.h b/include/grub/err.h
index 3435fb7..7a5ce1a 100644
--- a/include/grub/err.h
+++ b/include/grub/err.h
@@ -53,7 +53,8 @@ typedef enum
GRUB_ERR_BAD_GZIP_DATA,
GRUB_ERR_MENU,
GRUB_ERR_TIMEOUT,
- GRUB_ERR_IO
+ GRUB_ERR_IO,
+ GRUB_ERR_ACCESS_DENIED
}
grub_err_t;
diff --git a/include/grub/menu.h b/include/grub/menu.h
index 3bd25e8..c7114a9 100644
--- a/include/grub/menu.h
+++ b/include/grub/menu.h
@@ -32,6 +32,12 @@ struct grub_menu_entry
/* The title name. */
const char *title;
+ /* If set means not everybody is allowed to boot this entry. */
+ int restricted;
+
+ /* Allowed users. */
+ const char *users;
+
/* The classes associated with the menu entry:
used to choose an icon or other style attributes.
This is a dummy head node for the linked list, so for an entry E,
diff --git a/include/grub/normal.h b/include/grub/normal.h
index 7d8122a..feebc85 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -56,7 +56,7 @@ void grub_cmdline_run (int nested);
/* Defined in `cmdline.c'. */
int grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
- int echo_char, int readline);
+ int echo_char, int readline, int history);
grub_err_t grub_set_history (int newsize);
/* Defined in `completion.c'. */
diff --git a/normal/auth.c b/normal/auth.c
new file mode 100644
index 0000000..5431d58
--- /dev/null
+++ b/normal/auth.c
@@ -0,0 +1,254 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct grub_auth_user
+{
+ struct grub_auth_user *next;
+ char *name;
+ grub_auth_callback_t callback;
+ void *arg;
+ int authenticated;
+};
+
+struct grub_auth_user *users = NULL;
+
+int
+grub_auth_strcmp (const char *user_input, const char *template)
+{
+ int ok = 1;
+ const char *ptr1, *ptr2;
+ for (ptr1 = user_input, ptr2 = template; *ptr1; ptr1++)
+ if (*ptr1 == (ptr2 ? *ptr2 : ptr1[1]) && ok && ptr2 != NULL)
+ ptr2++;
+ else
+ ok = 0;
+
+ return !ok;
+}
+
+int
+grub_auth_strword (const char *haystack, const char *needle)
+{
+ const char *n_pos = needle;
+ int found = 0;
+
+ while (grub_iswordseparator (*haystack))
+ haystack++;
+
+ while (*haystack)
+ {
+ int ok = 1;
+ /* Crawl both the needle and the haystack word we're on. */
+ while(*haystack && !grub_iswordseparator (*haystack))
+ {
+ if (*haystack == *n_pos && ok)
+ n_pos++;
+ else
+ ok = 0;
+
+ haystack++;
+ }
+
+ if (ok)
+ found = 1;
+ }
+
+ return found;
+}
+
+grub_err_t
+grub_auth_register_authentication (const char *user,
+ grub_auth_callback_t callback,
+ void *arg)
+{
+ struct grub_auth_user *cur;
+
+ cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+ if (!cur)
+ cur = grub_zalloc (sizeof (*cur));
+ if (!cur)
+ return grub_errno;
+ cur->callback = callback;
+ cur->arg = arg;
+ if (! cur->name)
+ {
+ cur->name = grub_strdup (user);
+ if (!cur->name)
+ {
+ grub_free (cur);
+ return grub_errno;
+ }
+ grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+ }
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_unregister_authentication (const char *user)
+{
+ struct grub_auth_user *cur;
+ cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+ if (!cur)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+ if (!cur->authenticated)
+ {
+ grub_free (cur->name);
+ grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+ grub_free (cur);
+ }
+ else
+ {
+ cur->callback = NULL;
+ cur->arg = NULL;
+ }
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_authenticate (const char *user)
+{
+ struct grub_auth_user *cur;
+
+ cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+ if (!cur)
+ cur = grub_zalloc (sizeof (*cur));
+ if (!cur)
+ return grub_errno;
+
+ cur->authenticated = 1;
+
+ if (! cur->name)
+ {
+ cur->name = grub_strdup (user);
+ if (!cur->name)
+ {
+ grub_free (cur);
+ return grub_errno;
+ }
+ grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_deauthenticate (const char *user)
+{
+ struct grub_auth_user *cur;
+ cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+ if (!cur)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+ if (!cur->callback)
+ {
+ grub_free (cur->name);
+ grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+ grub_free (cur);
+ }
+ else
+ cur->authenticated = 0;
+ return GRUB_ERR_NONE;
+}
+
+static int
+is_authenticated (const char *userlist)
+{
+ const char *superusers;
+
+ auto int hook (grub_list_t item);
+ int hook (grub_list_t item)
+ {
+ const char *name;
+ if (!((struct grub_auth_user *) item)->authenticated)
+ return 0;
+ name = ((struct grub_auth_user *) item)->name;
+
+ return (userlist && grub_auth_strword (userlist, name))
+ || grub_auth_strword (superusers, name);
+ }
+
+ superusers = grub_env_get ("superusers");
+
+ if (!superusers)
+ return GRUB_ERR_NONE;
+
+ return grub_list_iterate (GRUB_AS_LIST (users), hook);
+}
+
+grub_err_t
+grub_auth_check_authentication (const char *userlist)
+{
+ char login[1024] = {0};
+ struct grub_auth_user *cur = NULL;
+ grub_err_t err;
+
+ auto int hook (grub_list_t item);
+ int hook (grub_list_t item)
+ {
+ if (grub_auth_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
+ {
+ cur = (struct grub_auth_user *) item;
+ return 1;
+ }
+ return 0;
+ }
+
+ auto int hook_any (grub_list_t item);
+ int hook_any (grub_list_t item)
+ {
+ if (((struct grub_auth_user *) item)->callback)
+ {
+ cur = (struct grub_auth_user *) item;
+ return 1;
+ }
+ return 0;
+ }
+
+ if (is_authenticated (userlist))
+ return GRUB_ERR_NONE;
+
+ if (!grub_cmdline_get ("Enter username: ", login, sizeof (login) - 1,
+ 0, 0, 0))
+ return GRUB_ACCESS_DENIED;
+
+ grub_list_iterate (GRUB_AS_LIST (users), hook);
+
+ if (!cur || ! cur->callback)
+ {
+ grub_list_iterate (GRUB_AS_LIST (users), hook_any);
+
+ /* No users present at all. */
+ if (!cur)
+ return GRUB_ACCESS_DENIED;
+
+ /* Display any of available authentication schemes. */
+ err = cur->callback (login, 0);
+
+ return GRUB_ACCESS_DENIED;
+ }
+ err = cur->callback (login, cur->arg);
+ if (is_authenticated (userlist))
+ return GRUB_ERR_NONE;
+ return GRUB_ACCESS_DENIED;
+}
diff --git a/normal/cmdline.c b/normal/cmdline.c
index 9a07d7d..56f8921 100644
--- a/normal/cmdline.c
+++ b/normal/cmdline.c
@@ -181,7 +181,7 @@ print_completion (const char *item, grub_completion_type_t type, int count)
/* FIXME: The dumb interface is not supported yet. */
int
grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
- int echo_char, int readline)
+ int echo_char, int readline, int history)
{
unsigned xpos, ypos, ystart;
grub_size_t lpos, llen;
@@ -280,7 +280,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
cl_insert (cmdline);
- if (hist_used == 0)
+ if (history && hist_used == 0)
grub_history_add (buf);
while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
@@ -468,11 +468,14 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
while (buf[lpos] == ' ')
lpos++;
- histpos = 0;
- if (grub_strlen (buf) > 0)
+ if (history)
{
- grub_history_replace (histpos, buf);
- grub_history_add ("");
+ histpos = 0;
+ if (grub_strlen (buf) > 0)
+ {
+ grub_history_replace (histpos, buf);
+ grub_history_add ("");
+ }
}
grub_memcpy (cmdline, buf + lpos, llen - lpos + 1);
diff --git a/normal/main.c b/normal/main.c
index 66d8418..748eef8 100644
--- a/normal/main.c
+++ b/normal/main.c
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#define GRUB_DEFAULT_HISTORY_SIZE 50
@@ -164,6 +165,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
int i;
struct grub_menu_entry_class *classes_head; /* Dummy head node for list. */
struct grub_menu_entry_class *classes_tail;
+ char *users = NULL;
/* Allocate dummy head node for class list. */
classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class));
@@ -218,6 +220,18 @@ grub_normal_add_menu_entry (int argc, const char **args,
classes_tail = new_class;
continue;
}
+ else if (grub_strcmp(arg, "users") == 0)
+ {
+ i++;
+ users = grub_strdup (args[i]);
+ if (! users)
+ {
+ failed = 1;
+ break;
+ }
+
+ continue;
+ }
else
{
/* Handle invalid argument. */
@@ -275,6 +289,9 @@ grub_normal_add_menu_entry (int argc, const char **args,
(*last)->title = menutitle;
(*last)->classes = classes_head;
+ if (users)
+ (*last)->restricted = 1;
+ (*last)->users = users;
(*last)->sourcecode = menusourcecode;
menu->size++;
@@ -465,7 +482,19 @@ quit:
void
grub_cmdline_run (int nested)
{
- grub_reader_t reader = grub_reader_get_current ();
+ grub_reader_t reader;
+ grub_err_t err = GRUB_ERR_NONE;
+
+ err = grub_auth_check_authentication (NULL);
+
+ if (err)
+ {
+ grub_print_error ();
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
+
+ reader = grub_reader_get_current ();
reader_nested = nested;
if (reader->init)
@@ -501,7 +530,7 @@ grub_normal_read_line (char **line, int cont)
while (1)
{
cmdline[0] = 0;
- if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1))
+ if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
break;
if ((reader_nested) || (cont))
diff --git a/normal/menu.c b/normal/menu.c
index 59ad83f..8ee7d1c 100644
--- a/normal/menu.c
+++ b/normal/menu.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
/* Get a menu entry by its index in the entry list. */
grub_menu_entry_t
@@ -124,6 +125,18 @@ get_and_remove_first_entry_number (const char *name)
void
grub_menu_execute_entry(grub_menu_entry_t entry)
{
+ grub_err_t err = GRUB_ERR_NONE;
+
+ if (entry->restricted)
+ err = grub_auth_check_authentication (entry->users);
+
+ if (err)
+ {
+ grub_print_error ();
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
+
grub_parser_execute ((char *) entry->sourcecode);
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
diff --git a/normal/menu_entry.c b/normal/menu_entry.c
index f7662ff..75a6377 100644
--- a/normal/menu_entry.c
+++ b/normal/menu_entry.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
enum update_mode
{
@@ -1026,6 +1027,16 @@ grub_menu_entry_run (grub_menu_entry_t entry)
{
struct screen *screen;
int prev_c;
+ grub_err_t err = GRUB_ERR_NONE;
+
+ err = grub_auth_check_authentication (NULL);
+
+ if (err)
+ {
+ grub_print_error ();
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
screen = make_screen (entry);
if (! screen)
diff --git a/normal/menu_viewer.c b/normal/menu_viewer.c
index 37d317b..1bd271a 100644
--- a/normal/menu_viewer.c
+++ b/normal/menu_viewer.c
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
/* The list of menu viewers. */
static grub_menu_viewer_t menu_viewer_list;
@@ -55,9 +56,26 @@ grub_err_t
grub_menu_viewer_show_menu (grub_menu_t menu, int nested)
{
grub_menu_viewer_t cur = get_current_menu_viewer ();
+ grub_err_t err1, err2;
if (!cur)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available.");
- return cur->show_menu (menu, nested);
+ while (1)
+ {
+ err1 = cur->show_menu (menu, nested);
+ grub_print_error ();
+
+ err2 = grub_auth_check_authentication (NULL);
+ if (err2)
+ {
+ grub_print_error ();
+ grub_errno = GRUB_ERR_NONE;
+ continue;
+ }
+
+ break;
+ }
+
+ return err1;
}