Автор Тема: smbstatus - как разобрать вывод  (Прочитано 852 раз)

Оффлайн fraks

  • Начинающий
  • *
  • Сообщений: 14
Всем привет.

Задача - найти кто открыл и тем самым заблокировал файл на шаре, что бы повлиять на этого чела.
Как делать - понятно. Смотрим smbstatus -L и потом по PID в том же выводе smbstatus смотрим кто это и с какого ip.
Хотелось бы это обернуть в скриптик что бы сделать более удобным процесс поиска.

Проблема  в том что вывод smbstatus -L не поддается разбору на поля. В той части которая нас в первую очередь интересует, а именно:
SharePath   Name   Time

Locked files:
Pid          Uid        DenyMode   Access      R/W        Oplock           SharePath   Name   Time
--------------------------------------------------------------------------------------------------
26450        1010       DENY_NONE  0x100081    RDONLY     NONE             /samba/_relay/bank   .   Fri Aug 12 09:42:03 2022
26581        1055       DENY_NONE  0x100081    RDONLY     NONE             /samba/nik   Документы/Инвестор/Город Псков   Fri Aug 12 10:33:29 2022
26581        1055       DENY_NONE  0x100080    RDONLY     NONE             /samba/nik   .   Fri Aug 12 10:15:50 2022
26081        1026       DENY_NONE  0x100081    RDONLY     NONE             /samba/oksana   .   Fri Aug 12 08:44:41 2022

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

Вопросы:

 * Можно ли корректно разобрать вывод smbstatus -L на поля?
 * Можно ли получить информацию в каком-то машиночитаемом виде (csv, json, xml и т. п.)
 * Можно ли получить ту же самую инфу не через вывод smbstatus?
 * Можно ли Time получить в формате unixtime?


Оффлайн Skull

  • Глобальный модератор
  • *****
  • Сообщений: 19 908
    • Домашняя страница
    • Email
Re: smbstatus - как разобрать вывод
« Ответ #1 : 12.08.2022 10:13:30 »
Скорее всего, будет проще через python3-module-samba
Андрей Черепанов (cas@)

Оффлайн fraks

  • Начинающий
  • *
  • Сообщений: 14
Re: smbstatus - как разобрать вывод
« Ответ #2 : 12.08.2022 10:54:44 »
Питоний апи - это видимо неплохо на будущее, но пока я питоном не владею.

Попытка найти модуль в этом python3-module-samba который бы делал искомое, что бы был смысл погрузиться в эту тему - успехов не дали.
Если кто ткнет пальцем - было бы Ок.

Кроме того, в эксплуатации есть
# smbstatus -V
Version 3.0.26a
к которому, как я понял, API на питоне еще не было прикручено.

Нашел разбор файла на php, но как я понимаю, там тоже есть некие допущения по именованию шар и файлов.

https://github.com/35niavlys/smbstatus/
   
    $part3[] = split("[ ]+",$smbstatus[$k],8);

    $pid = $part3[$k-$j-3][0];
    $uid = $part3[$k-$j-3][1];
    $deny_mode = $part3[$k-$j-3][2];
    $access = $part3[$k-$j-3][3];
    $rw = $part3[$k-$j-3][4];
    $oplock = $part3[$k-$j-3][5];
    $service = end(explode("/",$part3[$k-$j-3][6]));
    $name = htmlspecialchars(trim(substr_replace($part3[$k-$j-3][7],"",-25)));
    $time = trim(substr($part3[$k-$j-3][7], strlen($part3[$k-$j-3][7])-25, 25));

    $locks[] = array($name,$pid,$uid,$deny_mode,$access,$rw,$oplock,$service,$time);


И вот такое оно не разберет корректно
# smbstatus -L | grep банк
28795        1000       DENY_WRITE 0x3019f     RDWR       EXCLUSIVE+BATCH  /home/_relay/bankv/Выписки из банка - ООО Феникс   ~$Лист Microsoft Excel.xlsx   Fri Aug 12 14:05:39 2022
28795        1000       DENY_WRITE 0x2019f     RDWR       NONE             /home/_relay/bankv/Выписки из банка - ООО Феникс   Лист Microsoft Excel.xlsx   Fri Aug 12 14:05:39 2022
28795        1000       DENY_NONE  0x81        RDONLY     NONE             /home/_relay/bankv/Выписки из банка - ООО Феникс   .   Fri Aug 12 14:05:35 2022
28795        1000       DENY_NONE  0x81        RDONLY     NONE             /home/_relay/bankv/Выписки из банка - ООО Феникс   .   Fri Aug 12 14:05:35 2022
« Последнее редактирование: 12.08.2022 11:22:57 от fraks »

Оффлайн kessys

  • Завсегдатай
  • *
  • Сообщений: 624
Re: smbstatus - как разобрать вывод
« Ответ #3 : 12.08.2022 11:22:25 »
Так если мы говорим про документы офисных форматов то их при открывании блокирует сам LO, а чтобы найти у того кто открыл:
Ctrl + H и смотрим на файл ~название.lock и его открываем - этого достаточно
О подпись)
Жизнь с kde не так плоха, Но без ssd, это жестоко грустно.

Оффлайн Александр Ерещенко

  • Завсегдатай
  • *
  • Сообщений: 1 153
Re: smbstatus - как разобрать вывод
« Ответ #4 : 12.08.2022 11:29:04 »
Так если мы говорим про документы офисных форматов то их при открывании блокирует сам LO, а чтобы найти у того кто открыл:
Ctrl + H и смотрим на файл ~название.lock и его открываем - этого достаточно
Судя по файлу "~$Лист Microsoft Excel.xlsx", там используется и MS Office

Оффлайн fraks

  • Начинающий
  • *
  • Сообщений: 14
Re: smbstatus - как разобрать вывод
« Ответ #5 : 12.08.2022 11:31:08 »
Судя по файлу "~$Лист Microsoft Excel.xlsx", там используется и MS Office
Да, имеется разнообразие как операционок так и офисных пакетов, самых различных версий.

Оффлайн kessys

  • Завсегдатай
  • *
  • Сообщений: 624
Re: smbstatus - как разобрать вывод
« Ответ #6 : 12.08.2022 12:25:41 »
Судя по файлу "~$Лист Microsoft Excel.xlsx", там используется и MS Office
Да, имеется разнообразие как операционок так и офисных пакетов, самых различных версий.
Тогда есть понятие ещё что документы MO можно открывать для чтения, а вот с LO такая фишка не докатывает
О подпись)
Жизнь с kde не так плоха, Но без ssd, это жестоко грустно.

Оффлайн fraks

  • Начинающий
  • *
  • Сообщений: 14
Re: smbstatus - как разобрать вывод
« Ответ #7 : 06.09.2022 11:21:37 »
Углубился в изучение awk и задачу, в общем получилось решить, весьма просто.

Запускающий скрипт smbstatus-locked
#!/bin/bash
# Разбор вывода smbstatus что бы было понятно кто заблокировал файл
smbstatus | awk -f smbstatus.awk

И сам smbstatus.awk

function ConvertTime( s ) {
  #Fri Aug 12 12:08:46 2022
  #123456789012345678901234
  syear  = substr( s, 21, 4)
  smonth = substr( s,  5, 3)
  sday   = substr( s,  9, 2)
  stime  = substr( s, 12, 8)

  sub(/^[ ]/, "0", sday)                # заменим пробел на 0 у дат меньше 10

  switch( smonth ) {                    # заменим месяц с букв на цифры - так по ISO и сортировать удобно
    case "Jan" : smonth = "01"; break
    case "Feb" : smonth = "02"; break
    case "Mar" : smonth = "03"; break
    case "Apr" : smonth = "04"; break
    case "May" : smonth = "05"; break
    case "Jun" : smonth = "06"; break
    case "Jul" : smonth = "07"; break
    case "Aug" : smonth = "08"; break
    case "Sep" : smonth = "09"; break
    case "Oct" : smonth = "10"; break
    case "Nov" : smonth = "11"; break
    case "Dec" : smonth = "12"; break
    case "янв" : smonth = "01"; break
    case "фев" : smonth = "02"; break
    case "мар" : smonth = "03"; break
    case "апр" : smonth = "04"; break
    case "май" : smonth = "05"; break
    case "июн" : smonth = "06"; break
    case "июл" : smonth = "07"; break
    case "авг" : smonth = "08"; break
    case "сен" : smonth = "09"; break
    case "окт" : smonth = "10"; break
    case "ноя" : smonth = "11"; break
    case "дек" : smonth = "12"; break
  }
  return syear "-" smonth "-" sday " " stime
}

#---------------------------------------------------------------
BEGIN {
  FS = " "
}

#---------------------------------------------------------------
# обработаем диапазон строк которые начинаются от PID до Service
# тут перечень PID и соответствующие им user и ip
# неинтересующие нас записи с user=nobody пропустим
/^PID/, /^Service/ {
  if ($0 ~ /^[0123456789]/) {
    if ($2 != "nobody" ) {
      split($5, str, ":") # поле с ip-адресом разрежем по : что бы взять только сам ip, без типа протокола и без порта
      spid[$1 "user"]=$2
      spid[$1 "ip"  ]=str[2]
#     printf("%s|%s|%s \n", $1, spid[$1 "user"], spid[$1 "ip"])
    }
  }
}

#---------------------------------------------------------------
# обработаем диапазон строк которые начинаются от Locked files до конца файла
# к результату добавим расшифровку PID из массива spid набранного ранее
/^Locked files:/, /*/ {
  if ($0 ~ /^[0123456789]/) {
    i = index($0, "/" )
    if (i > 0) {
      # поделим строку на 2 части, по "/"
      SL=substr($0, 1, i-1)
      SR=substr($0, i)
      # левую часть поделим в массив по разделителю "пробел"
      # правую часть поделим в массив по разделителю "3 пробела подряд"
      split(SL, L, " ")
      split(SR, R, "[ ]{3}")
      # преобразуем дату-время в человеческий вид и положим на то же место откуда взяли
      R[3] = ConvertTime( R[3] )
      # и собственно, вывод нужной нам информации
      printf("| %7s | %10-s | %10-s | %10-s | %24-s | %10-s | %12-s | %s//%s\n",
                L[1],  L[3] , L[5]  , L[6]  , R[3], spid[L[1] "user"], spid[L[1] "ip"], R[1], R[2] )
#     printf("| %7s | %6s | %10-s | %10-s | %10-s | %10-s | %24-s | %10-s | %12-s | %s//%s\n",
#               L[1], L[2], L[3]  , L[4]  , L[5]  , L[6]  , R[3], spid[L[1] "user"], spid[L[1] "ip"], R[1], R[2] )
    }
  }
}

#---------------------------------------------------------------

По результату еще можно сделать sort и grep - и все Ок.

Оффлайн fraks

  • Начинающий
  • *
  • Сообщений: 14
Re: smbstatus - как разобрать вывод
« Ответ #8 : 06.09.2022 11:26:37 »
Тут тоже сделано допущение что в имени шары не может быть трех пробелов подряд, это вполне подконтрольно.
Если делать совсем правильно - то из правой части нужно дату брать не из третьего поля а из последнего, а в качестве имени файла взять все что между первым и последним, но уже лень :)
Если пользователи таки заведут файл с тремя пробелами - то этот тут же будет видно по поломанному полю дата-время - в него нарежет кусок имени файла.

Оффлайн fraks

  • Начинающий
  • *
  • Сообщений: 14
Re: smbstatus - как разобрать вывод
« Ответ #9 : 15.09.2022 07:56:36 »
И внезапно:

Цитировать
Выпуск Samba 4.17.0
...
В программе smbstatus реализована возможность вывода информации в формате JSON (включается опцией "--json").

А что, так можно было? :)