Welcome to zewaren.net. This site presents myself and mostly archives the solutions to some problems I once had.

How to cast a encoded UTF-8 string into a decoded UTF-8 string in PHP

Not so frequently asked questions and stuff: 

The situation

You have some PHP strings that are encoded in utf-8 twice. Using utf8_decode or mb_convert_encoding solves the problem, but you lose the characters that aren't common with the ISO8859-1 character set.

Solution

Create a function to cast the string as binary and convert it into a utf-8 string.

/*
utf8_cast()
Packs a string into binary and convert the result into a utf-8 string.
Useful if you have a utf-8 string in iso8859-1.
ZeWaren / Erwan Martin  September 2012.
Must not be used in a production environment since random behavior can be expected if input data is invalid.
*/
function utf8_cast($str, $ignore_errors=true) {
    $result = '';
 $a = unpack('C*', $str);
  for($i=1; $i> $shift--) & 0x1) {
         $c++;
       }
       if ($c) {
           if ($c == 1) {
              #First byte of a utf-8 character is not supposed to start by 0b10xxxxxx.
                if (!$ignore_errors) {
                  return $result;
             }
               continue;
           }
           #We're dealing with a unicode character. Let's find its value.
            $unicode_value = $achar & (63 >> ($c));
         $cd = $c;
           while(--$c) {
               $unicode_value = $unicode_value 

How to synchronize users and groups from Active Directory (including passwords) to virtually anything

Not so frequently asked questions and stuff: 

The situation

You have an Active Directory server with users and groups. You would like those to be synchronized with something else, be it a sql database, an openldap server, a text file, a samba passdb file, etc.

What you need

To achieve this, you will need:

  • Roles installed on your AD Server: Identity Management for Unix (including password synchronization and administration tools).
    Roles needed to achieve password synchronization
  • A script to fetch the users and the groups from AD using the LDAP protocol.
  • A script that will act as an SSO daemon to be able to synchronize passwords as well. (see http://support.microsoft.com/kb/324542 for more information on the subject). With this, you won't be able to extract the passwords currently stored in the AD server, but you will be notified of any change.

Download, install and configure pSSOd

pSSOd is a collection of perl scripts that provide the synchronization we want.

You can find the scripts on github at: https://github.com/ZeWaren/pSSOd.

In this example, the following hosts are involved:

  • 192.168.42.10: Windows Server 2008 R2.
  • 192.168.42.20: Debian Squeeze.

Configure password synchronization on the Windows host

  • Configure the properties of Password Synchronization
    Image
  • Add an UNIX computer and configure its properties.
    Password Synchronization Host properties
    Image
  • Configure and run perlsync

    Configure and run perlsync.pl to fetch everything you need except the passwords.

    Configure:

use constant LDAP_HOST => "192.168.42.10";
use constant LDAP_USER => "aduser\@grandopen.zwm.fr";
use constant LDAP_PASSWORD => "abcd1234___";
use constant LDAP_BASE => "DC=grandopen,DC=zwm,DC=fr";

Run:

root@debiantest:~# perl perlsync.pl
$VAR1 = {
          'CN=User One,CN=Users,DC=grandopen,DC=zwm,DC=fr' => {
                                                                'name' => 'User One',
                                                                'accountname' => 'uone'
                                                              },
          'CN=Guest,CN=Users,DC=grandopen,DC=zwm,DC=fr' => {
                                                             'name' => 'Guest',
                                                             'accountname' => 'Guest'
                                                           },
          'CN=AD User,CN=Users,DC=grandopen,DC=zwm,DC=fr' => {
                                                               'name' => 'AD User',
                                                               'accountname' => 'aduser'
                                                             },
[...]
        };
$VAR1 = {
          'Even Users' => {
                            'users' => [
                                         'usix',
                                         'ufour',
                                         'utwo'
                                       ],
                            'description' => 'Users that have an even id'
                          },
          'Group two' => {
                           'users' => [
                                        'usix',
                                        'ufive',
                                        'ufour'
                                      ],
                           'description' => 'This is the second group'
                         },
[...]
        };

Configure and start perlssod

Configure and start perlssod.pl in order to be notified of any password change.

Configure:

use constant SSOD_SECRET => "8MRQH_Pa62637f3fG]3T";
use constant SSOD_TCP_HOST => "192.168.42.20";
use constant SSOD_TCP_PORT => 6677;
use constant SSOD_DEBUG_MODE => 0;

Be sure to allow TCP connections between the two hosts, on port 6677.

Watch /var/log/pssod.log to know what is happening.

root@debiantest:/var/log# tail -f pssod.log
2012/09/11 15:52:59 INFO Starting pSSOd.
2012/09/11 15:53:19 INFO Calling callback with user ufour.
2012/09/11 15:53:19 INFO Inside callback with user ufour and password abcd1234$!!.

Complete the scripts

If everything works correctly, you now have a way to fetch the users and groups from the AD server, and a way to be notified of any password change.

You can now complete perlssod.pl and perlsync.pl to store the information where you need it.

Example scripts

Some example scripts are provided in the syncs_and_callbacks folder of pSSOd, to store the information into:

  • A SQL database (MySQL, Postgres, SQLite and whatever DBI supports)
  • Some htpasswd and htgroups files

Also, you can obviously build you own scripts depending on your needs.

How to allow non-administrator users to use RDP on a domain controller

Not so frequently asked questions and stuff: 

Situation

Your Windows Server 2008 is now a domain controller. Since you installed that role, you can't access the server through RDP/TSE.

Allow the users to use the service

If you are a non-administor user, you need to be authorized to use the service.

  • Run gpedit.msc
  • Browse to Computer Configuration -> Windows settings -> Security Settings -> Local policies -> User Rights Assignment
  • Edit "Allow log on through terminal services"
  • Run gpupdate /force

gpedit_domaincontroller_remotedesktop

Log-in with the right FQDN

Prior to installing your domain controller, you could login using only your username.

Now, when connecting, use the format user@f.q.d.n.example.net, or you won't be able to login.

Image

How to boot Linux Mint 13 using PXE

Prepare the tftp folder

  • Download pxelinux.0
  • Copy initrd.lz and vmlinux from the iso (casper folder)
  • pxelinux's config file (pxelinux.cfg/default):
    DEFAULT Linux-Mint-13-x86
    
    LABEL Linux-Mint-13-x86
    MENU LABEL Linux-Mint-13-x86
    KERNEL vmlinuz
    APPEND boot=casper netboot=nfs nfsroot=IP.ADD.RE.SS:/ initrd=initrd.lz quiet splash --
    

Which gives:

# ls tftproot
initrd.lz     pxelinux.0    pxelinux.cfg  vmlinuz

Prepare the NFS folder

  • Copy the required files from the casper folder

Which gives:

# ls nfsroot
casper

# ls nfsroot/casper
filesystem.manifest          filesystem.size
filesystem.manifest-desktop  filesystem.squashfs
filesystem.manifest-remove

Boot

Set up your DHCP, NFS and TFTP servers and boot your target.

Boot Kon-Boot 2.0 using PXE

PXE: 

What you need:

How to know which resources are called after using apache's http server's mod_rewrite.

Not so frequently asked questions and stuff: 

The situation

You set up rewrite rules in your apache configuration.

RewriteEngine On
RewriteRule    ^products/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$    product.php?category=$1&product=$2    [NC,L]
RewriteRule    ^blog/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$    blog.php?what=$1&post=$2    [NC,L]

If you have a problem, you would like to be able to see what urls are really called (after the rewriting).

Solution

Create a new log file, containing only the requested URL and the rewrited one.

    LogFormat "%r -> %f%q" rewriting
    CustomLog /var/log/apache2/access_rewriting.log rewriting

Content:

GET /products/cake/kouignamann/ HTTP/1.1 -> /var/www/product.php?category=cake&product=kouignamann
GET /products/beverages/cider/ HTTP/1.1 -> /var/www/product.php?category=beverages&product=cider
GET /blog/life/4269/ HTTP/1.1 -> /var/www/blog.php?what=life&post=4269

You can then know which scripts are actually called, along with their arguments.

smbldap-tools' "Failed to add entry for user"

Not so frequently asked questions and stuff: 

Situation

smbldap-populate populated the LDAP server correctly, but I didn't seem to be able to add users.

server# smbpasswd -a testuser1
smbldap_search_domain_info: Searching for:[(&(objectClass=sambaDomain)(sambaDomainName=NETBIOSNAME))]
smbldap_open_connection: connection opened
ldap_connect_system: successful connection to the LDAP server
The LDAP server is successfully connected
New SMB password:
Retype new SMB password:
ldapsam_getsampwnam: Unable to locate user [testuser1] count=0
Warning: homedirectory /home/testuser1 already exist. Check manually
_samr_create_user: Running the command `/usr/local/sbin/smbldap-useradd -m testuser1' gave 0
Could not find user testuser1, add script did not work
Failed to add entry for user testuser1.

Here is what was added into the LDAP server:

dn: uid=testuser1,ou=people,dc=example,dc=net
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: posixAccount
objectclass: shadowAccount
objectclass: inetOrgPerson
cn: testuser1
gidnumber: 513
homedirectory: /home/testuser1
sn: testuser1
uid: testuser1
uidnumber: 1012
gecos: System User
givenname: testuser1
loginshell: /bin/sh
userpassword: {crypt}x

You can see that the NT fields (sambaSID, sambaNTPassword, etc.) are missing, i.e. that the command did not complete.

Retrying with more debugging output (-D 10) showed:

smbldap_search_ext: base => [dc=example,dc=net], filter => [(&(uid=testuser1)(objectclass=sambaSamAccount))], scope => [2]
ldapsam_getsampwnam: Unable to locate user [testuser1] count=0

This is normal;

what is not is:

Get_Pwnam_internals didn't find user [testuser1]!

What the problem was

nss_ldap was not working. Apparently, samba can not work with LDAP without it.

Maybe I'd have known this if I had read the manual.

You know that nss_ldap is working if you can see samba's group in your system:

mmnas# getent group
[...]
Domain Admins:*:512:root
Domain Users:*:513
Domain Guests:*:514
Domain Computers:*:515
Administrators:*:544
Account Operators:*:548
Print Operators:*:550
Backup Operators:*:551
Replicators:*:552

Serve Clonezilla with PXE using TFTP on a legacy BIOS computer

AttachmentSize
Package icon pxe-clonezilla-live.zip118.74 KB
PXE: 

The system used here is a Windows XP.

Fetch the required files

What you need:

  • Clonezilla's zip file: clonezilla-live-1.2.12-10-amd64.zip
  • pxelinux.0
  • pxelinux's config file (pxelinux.cfg/default):
    DEFAULT Clonezilla-live
    
    LABEL Clonezilla-live
     MENU LABEL Clonezilla Live (Ramdisk)
     KERNEL vmlinuz
     APPEND initrd=initrd.img boot=live config noswap nolocales edd=on nomodeset ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_keymap="" ocs_live_batch="no" ocs_lang="" vga=788 nosplash noprompt fetch=tftp://[INSERT YOUR IP HERE]/filesystem.squashfs
    

Extract the files

Extract the required files from the zipfile.

live/vmlinuz live/initrd.img live/filesystem.squashfs

Configure

Edit pxelinux.cfg and insert your IP. You can also preset parameters (see http://clonezilla.org/show-live-doc-content.php?topic=clonezilla-live/doc/99_Misc.

Boot

Set up your DHCP and TFTP servers and boot your target.

Sources

Boot the BIOS update tools of MSI's K9N2 SLI Platinum / K9N2 Zilent using PXE

AttachmentSize
Package icon pxe-bios-msi-7374v39.zip881.84 KB

The system used here is a Debian Squeeze.

Create the image:

You will need:

  • 7374v39.zip (or newer)
  • FreeDOS
zwm-server:~/msi# wget "http://download1.msi.com/files/downloads/bos_exe/7374v39.zip"
zwm-server:~/msi# wget "ftp://ftp.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/fdboot.img"

Mount the FreeDOS image and unzip the utility:

zwm-server:~/msi# mkdir fdboot ourimage
zwm-server:~/msi# unzip 7374v39.zip
zwm-server:~/msi# mount -o loop fdboot.img fdboot

Create and mount a 3MB fat image:

zwm-server:~/msi# dd if=/dev/zero of=ourimage.img bs=1M count=3
zwm-server:~/msi# apt-get install dosfstools
zwm-server:~/msi# mkfs.msdos ourimage.img
zwm-server:~/msi# mount -o loop ourimage.img ourimage

Copy the FreeDOS files and the CD contents to the newly created image disk:

zwm-server:~/msi# cp -r fdboot/* ourimage/
zwm-server:~/msi# mkdir ourimage/msi
zwm-server:~/msi# cp -r 7374v39/* ourimage/msi/

Umount eveything:

zwm-server:~/msi# umount ourimage/
zwm-server:~/msi# umount fdboot/

Copy the boot sector from the original FreeDOS image to ours:

zwm-server:~/western# dd if=fdboot.img of=ourimage.img bs=1 count=446 seek=62 skip=62 conv=notrunc

Boot the image:

What you need:

  • pxelinux.0
  • memdisk
  • pxelinux's config file (pxelinux.cfg/default):
    DEFAULT msi_bios
    
    LABEL msi_bios
      KERNEL memdisk
      INITRD ourimage.img
    

Boot your computer, start FreeDOS and run the BIOS update utility from the MSI folder.

Sources:

Things you might try to restore your windows networking after malware cleaning.

Not so frequently asked questions and stuff: 

Introduction

Here is the situation: you removed a malware manually since any anti malware could not do anything beyond detecting the corrupted files. In the process, you deleted some infected system files, including some which were part of the networking stack.

Symptoms

  • You can ping both local and internet IPs, so this mean ICMP and your hardware is working.
  • You cannot open any TCP/UDP connection (they all fail instantly (i.e. no timeout)).
  • DHCP does not work either.

Things you might try

Check that your LSP stack is correct and not damaged

Run LSP-Fix

Resetting the networking stack

> netsh int ip reset reset.log
> netsh winsock reset catalog

Restoring any missing or corrupted system files

> sfc /scannow

Checking that the AFD service is started

> sc qc afd
> sc query afd

If AFD is not started, check that its service definition and its device exist in the registry.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD]
"DisplayName"="AFD"
"Description"="Environnement de prise en charge de réseau AFD"
"Group"="TDI"
"ImagePath"="\\SystemRoot\\System32\\drivers\\afd.sys"
"Start"=dword:00000001
"Type"=dword:00000001
"ErrorControl"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Security]
"Security"=hex:01,00,14,80,90,00,00,00,9c,00,00,00,14,00,00,00,30,00,00,00,02,\
  00,1c,00,01,00,00,00,02,80,14,00,ff,01,0f,00,01,01,00,00,00,00,00,01,00,00,\
  00,00,02,00,60,00,04,00,00,00,00,00,14,00,fd,01,02,00,01,01,00,00,00,00,00,\
  05,12,00,00,00,00,00,18,00,ff,01,0f,00,01,02,00,00,00,00,00,05,20,00,00,00,\
  20,02,00,00,00,00,14,00,8d,01,02,00,01,01,00,00,00,00,00,05,0b,00,00,00,00,\
  00,18,00,fd,01,02,00,01,02,00,00,00,00,00,05,20,00,00,00,23,02,00,00,01,01,\
  00,00,00,00,00,05,12,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Enum]
"0"="Root\\LEGACY_AFD\\0000"
"Count"=dword:00000001
"NextInstance"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\LEGACY_AFD]
"NextInstance"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\LEGACY_AFD\0000]
"Service"="AFD"
"Legacy"=dword:00000001
"ConfigFlags"=dword:00000000
"Class"="LegacyDriver"
"ClassGUID"="{8ECC055D-047F-11D1-A537-0000F8753ED1}"
"DeviceDesc"="AFD"
"Capabilities"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\LEGACY_AFD\0000\LogConf]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\LEGACY_AFD\0000\Control]
"ActiveService"="AFD"

Also, be sure to have a correct version of afd.sys in your system32/drivers/ folder.

Checking that other important services are started

Read the instructions at: http://www.smartestcomputing.us.com/topic/49542-cant-start-windows-firewall%3B-windows-firewall-service-missing-fix/

[Attached].

Run WinSockXPFix (XP Only)

Download and run WinSockXPFix.

Reset Internet Settings

Reset all the settings to default.

  • Control Panel -> Internet Options
  • Advanced tab
  • Reset Internet Explorer

Check connection settings and remove any proxy.

  • Control Panel -> Internet Options
  • Connections -> LAN Settings
  • Check all params

Pages

Subscribe to Front page feed