# Importada de Alpine aports por `takana import-alpine` (Etapa G). PUNTO DE PARTIDA — pero # YA trae los parches de musl de Alpine (lo que un import de nix pierde). Pendiente: el # sha256 del tarball (el wrapper lo calcula), y adaptar build/install del shell de abuild. # # ⚠ CONSECUENCIA MEDIDA DE `--disable-account-tools-setuid` (2026-09-21, caja `takana`): para un # usuario que NO sea root, `chsh`, `passwd`, `su`, `chfn` y `newgrp` **no funcionan**. El síntoma # no menciona setuid por ningún lado: # # $ su sergio -c "chsh -s /bin/bash" # Cannot change ID to root. # # La bandera vino en el import de Alpine —allá esos binarios los hace setuid el empaquetado, no el # configure— y acá no hay quien se lo reponga: el artefacto sale `r-xr-xr-x` del store. Y aunque la # receta lo pusiera, **`ArtifactHash::of_tree` sólo hashea el bit de EJECUCIÓN** (`mode & 0o111`), # así que hoy el modelo de artefactos no puede ni expresar ni garantizar un binario setuid. # # Quitar la bandera NO alcanza y además es una decisión de seguridad, no un arreglo de receta: # un setuid root en una distro de artefactos sellados necesita su propia conversación (¿quién lo # pone, quién lo verifica, y qué pasa cuando el hash no lo cubre?). Ver SDD 28 §5.11. name = "shadow" version = "4.18.0" license = "BSD-2-Clause" [source] tarball = "https://github.com/shadow-maint/shadow/releases/download/4.18.0/shadow-4.18.0.tar.xz" # FIXME sha256: el wrapper lo calcula (Alpine publica sha512). sha512 de Alpine: # sha512 = "e724670362949ccb570bb300322eb280c28ad609d631072b8db15a5e6eeba9fb9ac5d3df1df270f8b894235e4995b56c0e8f9aadb34d66bb5cea9b7a4f55e6ce" sha256 = "add4604d3bc410344433122a819ee4154b79dd8316a56298c60417e637c07608" patches = ["useradd-defaults.patch"] [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" flags = [] [build.phases] # fase configure EXPLÍCITA: si la receta no la define, takana autogenera su propio # `./configure --prefix=/usr` (sin nuestros --disable-*) e ignora estos flags. # De-Alpinizada: sin PAM (musl trae crypt), sin selinux/audit/acl/attr, estático musl. configure = ''' ./configure \ --build=$CBUILD \ --host=$CHOST \ --prefix=/usr \ --libdir=/usr/lib \ --sysconfdir=/etc \ --mandir=/usr/share/man \ --localstatedir=/var \ --disable-nls \ --disable-shared \ --enable-static \ --disable-account-tools-setuid \ --without-libbsd \ --without-libpam \ --without-audit \ --without-selinux \ --without-acl \ --without-attr \ --without-tcb \ --with-yescrypt \ --without-nscd \ --without-fcaps ''' compile = ''' # libtool se come el `-static` (lo lee como flag de libtool, no de link real). # El único camino a binarios musl 100% estáticos es su flag propio `-all-static`. make LDFLAGS="-all-static" ''' # de package() de Alpine (traducido $pkgdir→/out), sin los pam.d de aports: install = ''' make DESTDIR="/out" install make -C man DESTDIR="/out" install-man || true cd "/out" # Avoid conflict with man-pages package. rm -f usr/share/man/man3/getspnam.3* rm -f usr/share/man/man5/passwd.5* # /etc/login.defs is not very useful - replace it with an *almost* blank file. rm -f etc/login.defs echo "USERGROUPS_ENAB yes" > etc/login.defs echo "UID_MIN 1000" >> etc/login.defs # Used e.g. for unprivileged LXC containers. install -m644 /dev/null etc/subuid install -m644 /dev/null etc/subgid ''' # deps de Alpine remapeadas al catálogo canónico. AUSENTES quitadas: # linux-pam, libbsd, setcap. Sin fcaps (setcap falla en el sandbox) ⇒ sin libcap. [deps] build = ["linux-headers", "make"] # ── EL BIT DE PRIVILEGIO (SDD 28 §5.11, `[[setuid]]`) ───────────────────────────────────────────── # Declarado el 2026-10-15, al medir los artefactos del store: los binarios de abajo salen todos # `-rwxr-xr-x` y en cualquier otra distro son setuid. El hueco estaba ANOTADO —el encabezado de # `crates/takana-core/src/setuid.rs` los lista uno por uno— y era LATENTE mientras el instalador # solo pusiera contrasena de root. Desde que `lib/cuenta.sh` crea una cuenta de persona, dejo de # ser latente: hay un humano no-root que los choca a todos. # # Es metadato (fuera de `hash_inputs`), asi que entra en una receta YA SELLADA sin mover un solo # `ArtifactHash` — comprobado con `takana hash --check` antes y despues. [[setuid]] path = "bin/su" mode = "4755" why = "cambiar de usuario desde una sesion que no es root. Sin el bit contesta «su: must be suid to work properly» (busybox) o «Authentication failure» (shadow), y en los dos casos el mensaje manda a buscar la contrasena y no el permiso. Medido en metal el 2026-10-15, cuando era la unica escalada que le quedaba al operador." [[setuid]] path = "usr/bin/passwd" mode = "4755" why = "que el dueno de la maquina pueda cambiar SU PROPIA contrasena. Importa mas de lo que parece porque root queda cerrado por diseno cuando hay quien escale con doas: sin este bit, la contrasena de la persona solo se puede cambiar con `doas passwd`, y el que la olvida no tiene camino." [[setuid]] path = "usr/bin/newuidmap" mode = "4755" why = "escribe el uid_map de un user namespace sin privilegio. Lo pide la jaula de compilacion: `scripts/qorpa/qorpa-preflight.sh` ya lo comprueba y avisa «newuidmap SIN setuid y SIN capability — no puede escribir el uid_map», o sea que el hueco estaba detectado y sin cerrar." [[setuid]] path = "usr/bin/newgidmap" mode = "4755" why = "el par del anterior para el gid_map: los dos o ninguno, porque un namespace con uid mapeado y gid sin mapear falla al primer acceso a un fichero de grupo."