трудовые будни

Позднее Ctrl + ↑

получаем содержимое url (поддерживается http, https)

Бывает в приложении для windows нужно по ссылке получить какую нибудь информацию, ниже представлена функция, которая это сделает быстро и без дополнительных библиотек

function get_from_server(const Url: string): string;
const
  UserAgent = 'Mozilla/5.0 (compatible)';
var
  hInet: HINTERNET;
  hURL: HINTERNET;
  Buffer: array[0..1023] of AnsiChar;
  BufferLen: cardinal;
begin
  result := '';
  hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if hInet = nil then RaiseLastOSError;
  try
    hURL := InternetOpenUrl(hInet, PChar(URL), nil, 0, 0, 0);
    if hURL = nil then RaiseLastOSError;
    try
      repeat
        if not InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen) then
          RaiseLastOSError;
        result := result + UTF8Decode(Copy(Buffer, 1, BufferLen))
      until BufferLen = 0;
    finally
      InternetCloseHandle(hURL);
    end;
  finally
    InternetCloseHandle(hInet);
  end;
end;
11 апреля   free pascal   lazarus

получаем namingContexts контроллера домена

Некоторую информацию можно получить от контроллера домена без авторизации, например, namingContexts.

function get_ldap_namingContexts(server: string): string;
var
  ldap: TLDAPsend;
  attr: TStringList;
begin
  ldap:= TLDAPsend.Create;
  attr := TStringList.Create;
  attr.Add('namingContexts');
  try
       ldap.TargetHost := server;
       ldap.TargetPort := '389';
         if ldap.Login then
          begin
           if ldap.Bind then
            begin
              ldap.SearchScope:=SS_BaseObject;
              if ldap.Search('', False, '(objectClass=*)', attr) then
               begin
                  result:= ldap.SearchResult.Items[0].Attributes.Get('namingContexts')
               end;
            end;
           ldap.Logout;
          end;
  finally
     ldap.Free;
     attr.Free;
  end;
end;

результатом работы этой функции будет: DC=domain,DC=loc

про другие параметры можно почитать здесь: https://msdn.microsoft.com/en-us/library/ms684291(v=vs.85).aspx

11 апреля   free pascal   lazarus   ldapsend

путь к папке system32

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

function SystemFolder: string;
begin
  SetLength(Result, Windows.MAX_PATH);
  SetLength(
    Result, Windows.GetSystemDirectory(PChar(Result), Windows.MAX_PATH)
  );
end;

обычно, результатом работы будет следующий путь: c:\windows\system32

11 апреля   free pascal   windows

ldapsend, получаем sid в hex формате

функция для тех, кто работает с LDAP (ActiveDirectory)

Все знают, что sid LDAP возвращает в формате bin, сконвертируем в hex строку. Функция делает запрос к серверу и получает objectSid пользователя по sAMAccountName, затем конвертирует его в строку hex с разделителями запятыми. Результатом работы функции будет строка: 01,05,00,00,00,00,00,05,15,00,00,00,8a,1c,a9,8e,20,29,32,58,4f,d1,a7,56,50,04,00,00

фильтр запроса (&(objectClass=user)(sAMAccountName=’+user_name+’)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) исключает заблокированные учетные записи.

не забудьте подключить модуль ldapsend из библиотеки Synapse http://synapse.ararat.cz/doku.php/

function get_bin_sid_by_name(user_name,server,user,password,namingContexts: string): string;
var
  ldap: TLDAPsend;
  attr: TStringList;
  s,str:string;
  l:PAnsiChar;
  l_l:integer;
begin
  ldap:= TLDAPsend.Create;
  attr := TStringList.Create;
  attr.Add('cn');
  attr.Add('sAMAccountName');
  attr.Add('objectSid');
  result:='';

  try
    ldap.TargetHost := server;
    ldap.TargetPort := '389';
    ldap.UserName := user+'@'+copy(namingContexts,4,pos(',', namingContexts)-4);
    ldap.Password := password;
    ldap.SearchScope:=SS_WholeSubtree;
    ldap.SearchSizeLimit:=0;
    ldap.SearchTimeLimit:=0;


    if ldap.Login then
     begin
       if ldap.Bind then
        begin
          if ldap.Search('CN=users,'+namingContexts, False, '(&(objectClass=user)(sAMAccountName='+user_name+')(!(userAccountControl:1.2.840.113556.1.4.803:=2)))', attr) then
             begin
               s:=ldap.SearchResult.Items[0].Attributes.Get('objectSid');
               GetMem(l,length(s));
               BinToHex((@s[1]),l,length(s));
               result:=copy(l,1,length(s)*2);
               str:='';
               for l_l:=0 to length(s)*2 do
                 begin
                   if ((l_l mod 2 = 0) and (l_l<>0) and (l_l<>length(s)*2)) then
                     begin
                      str:=str+result[l_l]+',';
                     end
                   else
                     begin
                       str:=str+result[l_l];
                     end;
                 end;
               result:=trim(str);
             end;
        end;
     end;
  finally
     ldap.Free;
     attr.Free;
  end;
end;

user_name — sAMAccountName пользователя, чей sid хотим получить
server — адрес сервера LDAP
user — логин для авторизации
password — пароль пользователя (достаточно прав обычного пользователя домена для чтения атрибутов)
namingContexts — корень нашего домена, например dc=server,dc=loc

8 апреля   ActiveDirectory   free pascal   lazarus   ldapsend

Наблюдение за принтерами по SNMP

Удобно наблюдать состоянием картриджей сетевых принтеров с помощью следующего bash-скрипта:

#!/bin/bash

function isalive {
    ping -c 1 -i 0.2 -W 1 $1 &>/dev/null
    if [ $? -ne 0 ] ; then return 1;else return 0; fi
}

function show_ink
{
ip=$1
name=$2
mib_c="1.3.6.1.2.1.43.11.1.1.6"
mib_f="1.3.6.1.2.1.43.11.1.1.8"
mib_l="1.3.6.1.2.1.43.11.1.1.9"

full=($( snmpwalk -v1 -c public $ip $mib_f -Oa | awk -F "INTEGER: " '{print $2}'))
 cur=($( snmpwalk -v1 -c public $ip $mib_l -Oa | awk -F "INTEGER: " '{print $2}'))
echo '<td valign="top">'
echo '<b><a href="http://'$ip'/" name="'$name'" target="_blank">'$name'</a></b><br />'

for ((i = 0; i < ${#full[@]}; i++))
do
    x=${cur[$i]}
    y=${full[$i]}
    ii=$((i+1))
    level=`echo $x/$y*100|bc -l|awk -F "." '{print $1}'`
    if [ -z $level ]; then level=1; fi
    if [ `snmpwalk -v1 -c public $ip $mib_c.1.$ii -O0vs| awk -F ":" '{print $1}'| grep -i 'Hex-STRING'` ];then
        ink=`snmpwalk -v1 -c public $ip $mib_c.1.$ii -O0vsq | tr -d '\n' | xxd -r -p `
    else 
	ink=`snmpwalk -v1 -c public $ip $mib_c.1.$ii -O0vsq | tr -d '"'`
    fi
    if [ -z "$ink" ]; then
	continue
    fi
    if (( $level<0 )); then level=0; fi
    if (( $level<20 ));then
	if (( $level<1 ));then
	    echo '<font color="red"><b>'$ink:$level%'</b></font><br />'
	else
	    echo '<font color="goldenrod">'$ink:$level%'</font><br />'
	fi
    else
	echo $ink:$level%'<br />'
    fi
done
echo '</td>'
}
j=0
echo '<meta charset="utf-8">'
echo '<meta http-equiv="refresh" content="15" >'
echo '<table cellpadding="10">'
echo '<tr>'
while IFS='' read -r line || [[ -n "$line" ]]; do
    ip=`echo "$line"|awk '{print $1}'`
    name=`echo "$line"|awk -F"\"" '{print$2}'`
    if isalive $ip; then show_ink $ip "$name"; j=$(( j+1 )); fi
    if (( $j==3 )); then j=0;echo '</tr><tr>';fi
done < "/home/ipator/ink/printers.txt"
echo '</tr></table>'

Скрипт генерит страничку, из списка файла printers.txt

192.168.111.10 «HP 5550»
192.168.111.11 «HP m750»
192.168.111.12 «HP T795»
192.168.111.13 «HP T790»
192.168.111.14 «HP 5525»
192.168.111.15 «Epson 9880»
192.168.111.16 «Epson 3880»
192.168.111.17 «Epson SC-P800»
192.168.111.17 «HP M276»
192.168.111.18 «HP 1536»
192.168.111.19 «HP 1505»
192.168.111.20 «KX-MB2051»
192.168.111.21 «HP 400»
192.168.111.22 «HP 1212»
192.168.111.23 «HP 1606»
192.168.111.24 «HP M4276»

Получается вот такая страничка

Запускать скрипт можно через cron:

*/5 * * * * /opt/ink/showink.sh

3 апреля   bash   ink   pinter   snmp   toner
Ранее Ctrl + ↓