LINUX.ORG.RU

Ответ на: комментарий от realbarmaley

Никак кроме диверсии назвать ЭТО язык не поворачивается. Мне хочется верить, что это не злой умысел, а просто человеческая глупость.

Какая там глупость, не будте наивными.

systemd, dbus, polkitd+JS, BPF в ядре – все это классическая диверсия против GNU/Linux.

Навредил и сбежал к хозяйвам: https://www.opennet.ru/opennews/art.shtml?num=57464

anonymous
()
Ответ на: комментарий от rtxtxtrx

чтоб отказаться от паролей и одновременно защититься от опасных программ (браузер, wine — будут работать от другого пользователя).

teod0r ★★★★★
() автор топика
Последнее исправление: teod0r (всего исправлений: 1)
Ответ на: комментарий от anonymous

Это не в dbus, а udev правила надо писать

да, точно. что-то я перепутал dbus и udev.

https://wiki.gentoo.org/wiki/Allow_only_known_usb_devices

на сколько понимаю, это не то. мне нужно чтобы если в компьютере уже есть одна клавиатура, подключение второй было бы невозможно.

teod0r ★★★★★
() автор топика
Ответ на: комментарий от realbarmaley

лучше в таком случае и от systemd избавиться

в моей системе нет ни systemd, ни polkit, ни sudo, ни PAM (лишняя прослойка, всё равно мне от неё ничего не надо).

teod0r ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Если запущен X11 то он может перехватывать все нажатия на клавиатуру, зависит от настроек конкретного X11.

да, запущен. Как в иксах настроить, чтобы при нажатии кнопки питания и ctrl+alt+del посылались соответствующие сигналы иниту?

teod0r ★★★★★
() автор топика
Ответ на: комментарий от rtxtxtrx

просто смысл в том, что я не хочу вводить пароли, в том числе и для рута. также в системе обычные пользователи никак не должны повышать привелегии, т.е. обычный пользователь не должен иметь возможность стать рутом или каким-то другим пользователем.

teod0r ★★★★★
() автор топика
Ответ на: комментарий от teod0r

https://wiki.gentoo.org/wiki/Allow_only_known_usb_devices

на сколько понимаю, это не то. мне нужно чтобы если в компьютере уже есть одна клавиатура, подключение второй было бы невозможно.

Это именно то, даст гарантию что к твоему компьютеру подключена именно твоя клавиатура, и никакая чужая клава не подключится.

ЗЫ: лично PAM и tcpd считаю очень полезными и нужными.

Одна авторизация с плюшками, например в PAM есть поддержка CAP и не надо каждому приложению поддерживать свою авторизацию, можно слинковатся с libpam.

По уаналогии использование tcpd даст дополнительную фильтрацию и не надо каждому приложению писать поддержку сети, можно слинковатся с библиотеками tcpd.

anonymous
()
Ответ на: комментарий от anonymous

Это именно то, даст гарантию что к твоему компьютеру подключена именно твоя клавиатура, и никакая чужая клава не подключится.

просмотрел ещё раз статью, так и не понял, как там распознаётся своя/чужая? по серийному номеру?

teod0r ★★★★★
() автор топика
Ответ на: комментарий от teod0r

Не только по серийному, можно фильтровать по всем параметрам с вывода:

``udevadm info -a -p /sys/bus/usb/devices/3-1`

Например предлагаю: производителя, модель, серийник, название продукта, класс. Можно добавлять и удалять свои параметры фильтрации подключаемых устройств.

anonymous
()
Ответ на: комментарий от firkax
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
extern char **environ;
int main(int argc, char **argv) {
  argv[0] = "/usr/local/sbin/wrapped_script.sh";
  execve("/usr/local/sbin/wrapped_script.sh", argv, environ);
  fprintf(stderr, "execve(/usr/local/sbin/wrapped_script.sh) error %d (%s)\n", errno, strerror(errno));
  return -1;
}

то ли я что-то делаю не так...
скопировал содержимое в a.c, заменил путь к скрипту. сделал make a. сделал права

-rwsr-sr-x 1 root root 16256 May 19 04:56 "a"
в скрипте прописал sleep 1000. залогинился другим обычным юзером. запустил скомпилированную программу, и вижу что EUSER у sleep 1000 — user, не root!

teod0r ★★★★★
() автор топика
Ответ на: комментарий от teod0r

А, ещё забыл. Если из этого скрипта будешь вызывать другие - они себе так же откатят setuid если у них не указано -p. Это поведение в целом можно убрать, если в программе-обёртке в начало вставить setuid(0);. Но тогда будет другая проблема: поскольку информацию про сделанный setuid мы затёрли, узнать из скрипта какой юзер его на самом деле запустил уже не получится. В итоге есть разные варианты с тем, прятать ли setuid и если прятать, то когда, а так же с тем. кто и когда будет проверять права юзера-запускателя на выполнение действия. Главное - что проверить надо раньше чем затирать инфу о юзере.

firkax ★★★★★
()
Ответ на: комментарий от firkax

как оказалось, если в скрипте делать exec /bin/bash, то оно также откатывает setuid, даже если в самом скрипте указано -p. пришлось прописать setuid(0);
как мне теперь на C узнать какой юзер запустил программу-обёртку и как передать это в качестве аргумента скрипту?
ещё такой вопрос:
я хотел сделать программе-обёртке такие права для безопасности:
---Sr-x--- 1 root user 27 May 19 12:20 «suid_bash»
но программа не хочет запускаться от user, пока я не дам others права на чтение и исполнение, почему так?

teod0r ★★★★★
() автор топика
Ответ на: комментарий от teod0r

как оказалось, если в скрипте делать exec /bin/bash, то оно также откатывает setuid, даже если в самом скрипте указано -p

Думаю надо exec /bin/bash -p чтоб исправить это. Если не поможет или не хочешь, то способ ниже, но он длиннее.

пришлось прописать setuid(0); как мне теперь на C узнать какой юзер запустил программу-обёртку и как передать это в качестве аргумента скрипту?

Например вот:

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>

int main(void) {
  uid_t u1,u2,u3,u4,u5;
  u1 = getuid();
  u2 = geteuid();
  getresuid(&u3,&u4,&u5);
  printf("getuid() = %ld (caller uid)\n", (long)u1);
  printf("geteuid() = %ld (effective uid from suid flag)\n", (long)u2);
  printf("getresuid() = %ld %ld %ld (caller, effective, saved)\n", (long)u3, (long)u4, (long)u5);
  return 0;
}
getuid() - это uid вызывателя

geteuid() - это текущий действующий uid

третье число из getresuid() - это uid, на который было сделано переключение setuid-битом (он нужен для того чтоб setuid прога могла сначала понизить себе права до вызывателя а затем опять активировать повышенные, которые в нём запомнены)

setuid(), вызванный рутом, меняет все три числа. Чтобы менять только второе (не затирая информацию о setuid-бинарнике) есть сисколл seteuid().

Тебе проще всего вызвать getuid() а затем сделать setuid(0).

Передать аргументы, которых больше чем было изначально - немного муторно, т.к. придётся делать новый массив для них (в старом места под ещё один нет). Можно так:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

char ** merge_args(int argc, char **argv, char const *new_progname, size_t add_argc, char **add_argv) {
  size_t a, b;
  int i;
  char **args;
  i = a = ((size_t)argc) + add_argc + 2;
  if(argc<0 || i<=0 || a!=(size_t)i || a<2 || a-2<add_argc || (int)(a-2-add_argc)!=argc) { fprintf(stderr, "bad number of arguments (hack attempt)\n"); return NULL; }
  b = a*sizeof(char*);
  if(b/sizeof(char*)!=a || !(args = malloc(b))) { fprintf(stderr, "out of memory (too many arguments?)\n"); return NULL; }
  args[0] = (char*)new_progname;
  b = 1;
  if(add_argc) {
    memcpy(args+b, add_argv, add_argc*sizeof(char*));
    b += add_argc;
  }
  if(argc>=2) {
    memcpy(args+b, argv+1, ((size_t)(argc-1))*sizeof(char*));
    b += (argc-1);
  }
  args[b] = NULL;
  return args;
}

extern char **environ;
int main(int argc, char **argv) {
  char uidstr[50];
  char *add_argv[1];
  char **args;
  snprintf(uidstr, sizeof(uidstr), "%ld", (long)getuid());
  setuid(0);
  add_argv[0] = uidstr;
  if(!(args = merge_args(argc, argv, "/usr/local/sbin/wrapped_script.sh", 1, add_argv))) return -1;
  execve("/usr/local/sbin/wrapped_script.sh", args, environ);
  fprintf(stderr, "execve(/usr/local/sbin/wrapped_script.sh) error %d (%s)\n", errno, strerror(errno));
  return -1;
}

но программа не хочет запускаться от user, пока я не дам others права на чтение и исполнение, почему так?

По хорошему достаточно ---S--x--- (я проверил). Наверно потому что тот, кто пытается запустить, не состоит в группе «user». На всякий случай: настройки групп из /etc/passwd и /etc/group применяются только при логине и программами типа su, которые вручную их читают и применяют. Если ты переключался на юзера с помощью setuid-бинарника или с помощью сисколла setuid() то группы у него остаются те же что были до переключения. Если хочешь вручную прописывать группы то это делается через setgid() для основной и setgroups() для списка дополнительных.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Думаю надо exec /bin/bash -p чтоб исправить это.

Проблема в том, что приходится для всех дочерних скриптов тоже -p делать, не подходит.

По хорошему достаточно ---S--x--- (я проверил). Наверно потому что тот, кто пытается запустить, не состоит в группе «user»

Как оказалось, пришлось добавить user'a в группу user чтоб заработало. Странно, но раньше не сталкивался с таким, думал что user и так состоит по-умолчанию в своей дефолтной группе.
Но как оказалось, не факт, что мне нужна такая группа на обёртке (можно через ACL ограничить запуск только для user), т.к. оказалось нужно ещё чтобы группа рута тоже наследовалась. Но я попробовал повесить на обёртку sgid — не наследуется. Юзер (suid) наследуется, группа не наследуется, остаётся user. Не знаю почему, возможно где-то в системе настроил что-то для безопасности, пока не знаю куда смотреть. Пришлось прописать sg в скрипте.
Пока оставил первоначальный вариант обёртки + setuid(0);, группу user на обёртке + sg в скрипте. Работает.

teod0r ★★★★★
() автор топика