Set the Default Query Value on Laravel 4 Eloquent Model

Tags: October 4, 2013 7:01 AM

Sometimes we want to apply some default query to the Eloquent Model. In an example, suppose we have Post model that contains all posts. When retrieving the post we want to exclude post with status 'deleted' and 'draft'.

<?php
/**
 * Base class for all model
 */
namespace Acme\Models\BaseModel;

use Illuminate\Database\Eloquent\Model as Eloquent;

abstract class BaseModel extends Eloquent
{
    /**
     * Default value for this model. I.e. getting records that only
     * meet certain criteria.
     *
     * @var Boolean
     */
    protected static $useDefaultQuery = true;

    /**
     * The method that set flag for using default value or not.
     *
     * @return Illuminate\Database\Eloquent\Model
     */
    public static function noDefault()
    {
        static::$useDefaultQuery = false;
        
        return new static;
    }

    /**
     * All model should implements the default query here.
     */
    abstract protected function myDefaultQuery($query);

    /**
     * Override the laravel default newQuery() method so we can use the default value.
     */
    public function newQuery($excludeDeleted = true)
    {
        // Get the parent result
        $query = parent::newQuery($excludeDeleted);

        // Let's do the query if only the $useDefaultQuery property is true.
        if (static::$useDefaultQuery === true) {
            if (method_exists($this, 'myDefaultQuery') === true) {
                $query = $this->myDefaultQuery($query);
            }
        }

        return $query;
    }
}
Post model should extends from Acme\Models\BaseModel to implement the default query.
<?php
/**
 * Post model for retrieving all blog post.
 */
use Acme\Models\BaseModel;

class Post extends BaseModel
{
    /**
     * Apply the default query to the model.
     */
    protected function myDefaultQuery($query)
    {
        return $query->whereNotIn('post_status', array('deleted', 'draft'));
    }
}
If we want to disable the default query just wall the static method `noDefault()`.
// disable the default query
$posts = Post::noDefault()->get();

Share on Facebook Twitter

Mount /tmp with `noexec` and `nosuid` Options Inside chroot

Tags: January 15, 2013 6:55 AM
0 comments

To add extract security on chroot environment, it's better to make the /tmp directory cannot execute a file by mounting /tmp with 'noexec' and 'nosuid' options.

Create Partiotion

To simplify just create loopback device file for mounting /tmp later. (The size of partition for this example is 50MB)
  • /opt/jail: chroot directory
  • /opt/tmpdisk.img: loopback device
# dd if=/dev/zero of=/opt/tmpdisk.img bs=1M count=50
# mkfs.ext4 /opt/tmpdisk.img
# mount -o loop,rw,noexec,nosuid /opt/tmpdisk.img /opt/jail/tmp
Verify to make sure the mounted partition has 'noexec' and 'nosuid'.
# mount
----[SNIP]----
/opt/tmpdisk.img on /opt/jail/tmp type ext4 (rw,noexec,nosuid,commit=0)
----[SNIP]----

Test the /tmp

Try to execute some of executable file inside /tmp directory.
# cp /opt/jail/bin/ls /opt/jail/tmp/
# chroot /opt/jail /bin/bash
# /bin/ls
# /tmp/ls
bash: /tmp/ls: Permission denied
# /lib/ld-linux.so.2 /tmp/ls
/tmp/ls: error while loading shared libraries: /tmp/ls: failed to map segment from shared object: Operation not permitted
References

Share on Facebook Twitter

Fix "Whoami: Can't Find Name for User ID" Inside Chroot

Tags: January 8, 2013 7:46 PM
0 comments

Jika perintah whoami pada lingkungan chroot memunculkan pesan error seperti berikut:

whoami: cannot find name for user ID 0
Berarti ada yang salah dengan requirement yang dibutuhkan binary `whoami` entah itu shared library atau file-file konfigurasi.

Cara Memperbaiki

  1. Pastikan file /etc/passwd dan /etc/group isi dan permissionnya benar (0644).
  2. Pastikan terdapat file /etc/nsswitch.conf yang isinya kurang lebih seperti berikut:
    # /etc/nsswitch.conf
    #
    # Example configuration of GNU Name Service Switch functionality.
    # If you have the `glibc-doc-reference' and `info' packages installed, try:
    # `info libc "Name Service Switch"' for information about this file.
    
    passwd:         compat
    group:          compat
    shadow:         compat
    
    hosts:          files dns
    networks:       files
    
    protocols:      db files
    services:       db files
    ethers:         db files
    rpc:            db files
    
    netgroup:       nis
  3. Pastikan terdapat file-file konfigurasi PAM auth di /etc/pam.d/.
  4. Cek library apa saja yang diload ketika runtime dengan menggunakan program strace.
  5. Copy library-library tersebut dari Host ke lingkungan chroot. Dari observasi penulis, file-file yang perlu dicopy adalah:
    /lib/tls/i686/cmov/libnss_nis.so.2
    /lib/tls/i686/cmov/libnss_files.so.2
    /lib/tls/i686/cmov/libnss_compat.so.2
    /lib/tls/i686/cmov/libnsl.so.1
    
Reference

Share on Facebook Twitter

Minimal chroot Environment

Tags: January 7, 2013 11:21 PM
0 comments

I need to isolate the Mozilla Spidermonkey javascript shell. The goal is simple: Create a minimal chroot environment. So, here is my setup.

# mkdir /media/jail
# mkdir -p /media/jail/{bin,usr,lib,usr/lib,dev,sys,tmp,proc}
# chmod a+rwx /media/jail/tmp
# cp /bin/bash /media/jail/bash
Mount some special file systems and device files.
# mount -t proc proc /media/jail/proc
# mount -t sysfs -o rw,noexec,nosuid,nodev none /media/jail/sys
# mount -o bind /dev /media/jail/dev
# chroot /media/jail /bin/bash
Note: Use "mount" command to see what your system use for the proc, dev, sys, etc.

Reference

Share on Facebook Twitter

Shared Library Extractor

Tags: January 5, 2013 9:38 AM
0 comments

Untuk mempermudah penyalinan file-file library yang akan digunakan pada lingkungan chroot, penulis menggunakan shell script berikut.

#!/bin/bash
#
################################################################################
# Shell Script untuk melakukan otomasi penyalinan file-file yang diperlukan    #
# oleh sebuah binary/program.                                                  #
#                                                                              #
# @author Rio Astamal <me@rioastamal.net>                                      #
################################################################################
#
ACTION=$1
JAIL_FILE=$2
JAIL_ROOT=$3
LIST_FILES=

# cek apakah file ada
if [ ! -e $JAIL_FILE ]; then
 echo "Error: file '${JAIL_FILE}' tidak ditemukan."
 exit 2
fi

# cek apakah direktori target jail ada
if [ ! -d $JAIL_ROOT ]; then
 echo "Error: direktori jail '${JAIL_ROOT}' tidak ditemukan."
fi

show_help() {
 echo "Penggunaan: $0 [OPTIONS] [JAIL_FILE] [JAIL_ROOT]"
 echo ""
 echo "Dimana OPTIONS:"
 echo "  file - Mencetak daftar library."
 echo "  dir - Mencetak nama direktori dari daftar library."
 echo "  run - Melakukan penyalinan ke direktori JAIL_ROOT."
 echo ""
 echo "Contoh:"
 echo "$0 dir /usr/bin/nginx /opt/jail"
 echo ""
}

# Fungsi untuk mencetak daftar file library yang dibutuhkan oleh file binary
# yang ingin di-jail.
show_files() {
 LIST_FILES=`ldd $JAIL_FILE | awk '{print $3}' | grep ^/`
 LD_LINUX=`ldd $JAIL_FILE | grep ld-linux | awk '{print $1}'`
 
 for f in $LIST_FILES
 do
  echo $f
 done
 echo $LD_LINUX
}

# Fungsi untuk mencetak nama direktori dari setiap file library
show_directories() {
 LIST_FILES=`ldd $JAIL_FILE | awk '{print $3}' | grep ^/`
 LD_LINUX=`ldd $JAIL_FILE | grep ld-linux | awk '{print $1}'`
 
 for f in $LIST_FILES
 do
  dirname $f
 done
 dirname $LD_LINUX
}

if [ "$ACTION" == "file" ]; then
 show_files
elif [ "$ACTION" == "dir" ]; then
 show_directories
elif [ "$ACTION" == "run" ]; then
 # buat direktori tujuan dulu sebelum melakukan copy file
 for folder in `show_directories`
 do
  mkdir -p "${JAIL_ROOT}${folder}"
 done
 
 # copy setiap library
 for f in `show_files`
 do
  TARGET="${JAIL_ROOT}${f}"
  echo -n "Copying $f to ${TARGET}..."
  cp $f "${JAIL_ROOT}${f}" 2>/dev/null
  
  if [ $? -eq 0 ]; then
   echo "done."
  else
   echo "failed."
  fi
 done
fi

Simpan dengan nama ldd-extractor.sh lalu beri atribut +x.

Contoh Penggunaan

Melihat daftar shared library dari program "ncat".

# ldd-extractor file /usr/bin/ncat 
/lib/i686/cmov/libssl.so.0.9.8
/lib/i686/cmov/libcrypto.so.0.9.8
/usr/lib/libpcap.so.0.8
/lib/tls/i686/cmov/libdl.so.2
/lib/tls/i686/cmov/libc.so.6
/lib/libz.so.1
/lib/ld-linux.so.2

Melakukan penyalinan ke jail direktori yang telah ditentukan.

# ldd-extractor run /usr/bin/ncat /opt/jail
Copying /lib/i686/cmov/libssl.so.0.9.8 to /opt/jail/lib/i686/cmov/libssl.so.0.9.8...done.
Copying /lib/i686/cmov/libcrypto.so.0.9.8 to /opt/jail/lib/i686/cmov/libcrypto.so.0.9.8...done.
Copying /usr/lib/libpcap.so.0.8 to /opt/jail/usr/lib/libpcap.so.0.8...done.
Copying /lib/tls/i686/cmov/libdl.so.2 to /opt/jail/lib/tls/i686/cmov/libdl.so.2...done.
Copying /lib/tls/i686/cmov/libc.so.6 to /opt/jail/lib/tls/i686/cmov/libc.so.6...done.
Copying /lib/libz.so.1 to /opt/jail/lib/libz.so.1...done.
Copying /lib/ld-linux.so.2 to /opt/jail/lib/ld-linux.so.2...done.
Referensi:

Share on Facebook Twitter

Compile SpiderMonkey Ubuntu Linux

Tags: January 4, 2013 11:23 PM
0 comments

Install terlebih dahulu paket-paket dependency yang diperlukan sebelum melakukan kompilasi.

# apt-get install nspr4-dev autoconf2.13
Download source SpiderMonkey 1.8.5 pada http://ftp.mozilla.org/pub/mozilla.org/js/js185-1.0.0.tar.gz.
# cd /tmp/
# wget http://ftp.mozilla.org/pub/mozilla.org/js/js185-1.0.0.tar.gz
# mkdir spidermonkey
# tar -zxvf js185-1.0.0.tar.gz -C /tmp/spidermonkey
# cd spidermonkey/js-1.8.5/js/src
# autoconf2.13
# ./configure
# make
Setelah selesai akan terdapat file binary pada shell/js, dimana file tersebut adalah Javascript Shell Interpreter yang menggunakan engine SpiderMonkey.
# shell/js
js> for (var i=0; i<3; i++) {         
print("notes.rioastamal.net");  
}
notes.rioastamal.net
notes.rioastamal.net
notes.rioastamal.net

js> quit()

Share on Facebook Twitter