From 1e959cd634fb755ea68fa78d67b7f4a61112d526 Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Wed, 10 Jun 2026 23:53:47 -0300 Subject: [PATCH] uid: add /etc/shadow and check_password function MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Implement UID Infrastructure: autenticação real (completed). Added /etc/shadow file with basic entries (root:root, daemon:*, nobody:*). Updated Makefile to include /etc/shadow in initrd. Added check_password() function in pwd_grp.c to verify passwords against /etc/shadow. Added check_password() declaration in pwd.h. Password verification uses plaintext comparison for now (TODO: add SHA256/crypt). Locked accounts (passwd starts with '*' or '!') are rejected. Test: make test-battery PASS (157/157) --- Makefile | 5 +++-- rootfs/etc/shadow | 3 +++ user/ulibc/include/pwd.h | 3 +++ user/ulibc/src/pwd_grp.c | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 rootfs/etc/shadow diff --git a/Makefile b/Makefile index 1e360af2..cabf5453 100644 --- a/Makefile +++ b/Makefile @@ -265,14 +265,15 @@ USER_BIN_NAMES := $(filter-out init,$(USER_CMD_NAMES)) FSTAB := rootfs/etc/fstab RCS := rootfs/etc/init.d/rcS PASSWD := rootfs/etc/passwd +SHADOW := rootfs/etc/shadow INITRD_FILES := $(FULLTEST_ELF):sbin/fulltest \ $(USER_BUILD)/cmds/init/init.elf:sbin/init \ $(foreach cmd,$(USER_BIN_NAMES),$(USER_BUILD)/cmds/$(cmd)/$(cmd).elf:bin/$(cmd)) \ $(LDSO_ELF):lib/ld.so $(ULIBC_SO):lib/libc.so \ $(PIE_SO):lib/libpietest.so $(PIE_ELF):bin/pie_test \ - $(FSTAB):etc/fstab $(RCS):etc/init.d/rcS $(PASSWD):etc/passwd + $(FSTAB):etc/fstab $(RCS):etc/init.d/rcS $(PASSWD):etc/passwd $(SHADOW):etc/shadow -INITRD_DEPS := $(MKINITRD) $(FULLTEST_ELF) $(USER_CMD_ELFS) $(LDSO_ELF) $(ULIBC_SO) $(PIE_SO) $(PIE_ELF) $(FSTAB) $(RCS) $(PASSWD) +INITRD_DEPS := $(MKINITRD) $(FULLTEST_ELF) $(USER_CMD_ELFS) $(LDSO_ELF) $(ULIBC_SO) $(PIE_SO) $(PIE_ELF) $(FSTAB) $(RCS) $(PASSWD) $(SHADOW) # doom (build via 'make doom', included in initrd if present) doom: $(DOOM_SENTINEL) $(ULIBC_LIB) $(ULIBC_SO) diff --git a/rootfs/etc/shadow b/rootfs/etc/shadow new file mode 100644 index 00000000..830ad009 --- /dev/null +++ b/rootfs/etc/shadow @@ -0,0 +1,3 @@ +root:root:0:0:99999:7::: +daemon:*:0:0:99999:7::: +nobody:*:0:0:99999:7::: diff --git a/user/ulibc/include/pwd.h b/user/ulibc/include/pwd.h index dc0c64c4..1b9a6284 100644 --- a/user/ulibc/include/pwd.h +++ b/user/ulibc/include/pwd.h @@ -28,4 +28,7 @@ void setpwent(void); void endpwent(void); struct passwd* getpwent(void); +/* Password verification against /etc/shadow */ +int check_password(const char* username, const char* password); + #endif diff --git a/user/ulibc/src/pwd_grp.c b/user/ulibc/src/pwd_grp.c index 9bd5679b..a41b084a 100644 --- a/user/ulibc/src/pwd_grp.c +++ b/user/ulibc/src/pwd_grp.c @@ -15,7 +15,8 @@ #include /* /etc/passwd and /etc/group parsing with static fallback. - * Format: name:passwd:uid:gid:gecos:dir:shell */ + * Format: name:passwd:uid:gid:gecos:dir:shell + * /etc/shadow format: name:passwd:lastchg:min:max:warn:inactive:expire */ static struct passwd _root = { .pw_name = "root", @@ -207,3 +208,38 @@ struct group* getgrent(void) { if (_gr_idx == 0) { _gr_idx++; return &_root_grp; } return (struct group*)0; } + +/* Simple password verification against /etc/shadow (plaintext for now) */ +int check_password(const char* username, const char* password) { + if (!username || !password) return -1; + + FILE* fp = fopen("/etc/shadow", "r"); + if (!fp) return -1; + + char line[256]; + while (fgets(line, (int)sizeof(line), fp)) { + /* Parse shadow line: name:passwd:lastchg:min:max:warn:inactive:expire */ + char* saveptr = NULL; + char* name = strtok_r(line, ":\n", &saveptr); + if (!name) continue; + + if (strcmp(name, username) == 0) { + char* passwd = strtok_r(NULL, ":\n", &saveptr); + if (!passwd) { fclose(fp); return -1; } + + /* '*' or '!' means locked account */ + if (passwd[0] == '*' || passwd[0] == '!') { + fclose(fp); + return -1; + } + + /* Simple plaintext comparison (TODO: add SHA256/crypt) */ + int match = (strcmp(passwd, password) == 0); + fclose(fp); + return match ? 0 : -1; + } + } + + fclose(fp); + return -1; /* User not found */ +} -- 2.43.0