Roshan Book

My Tech Notebook

Category Archives: Tutorial

Learning Ruby Part 12 Changing data type and Declaring constant

c=13 (here c has a integer value)

c.to_f – This changes c data type to float

This type of data changing is called Casting

Similarly for strings

num = 10
num.to_s => “10”

Declaring a constant

Start with capital letter. Like Variable=10

Ruby lesson 1 basic

1. anything starting with ‘#’ is a comment
2. Classes names are in CamelCase while variable and functions are used_with_underscore
3. ALL_Uppercase for constants
4. Parenthesis () are for convenience and not a general rule. DO away with it whenever arguments are less, for conditional statements (if-else) and empty functions
5. puts is for print
6. You can insert multiple ruby statements in one line separated by ‘;’. Although try to follow one stement per line
7.

Starting YII development in ubuntu – Part 1

1. Download yii folder

2. Go to var/www directory in terminal

3. TO create a new project follow:

first you need to get into your webroot by

cd /var/www <– in my case

create a folder that you want your demo to be install in my case I create a folder named ‘blog’ under /var/www/yii/

then set permission to 777 by: sudo chmod 777

then type in the following command

php yii/framework/yiic.php webapp /var/www/yii/blog

if your php program has not been installed, the system will give you an install command then do it and come back to do the same.

then you can access your demo by http://localhost/yii/blog <— in my case

4. To enable gii

go to protected>config>main.php and uncomment gii module

5. To access gii generator go to http://localhost/myproj/demo/index.php?r=gii/default/login

6. To convert url mapping into path format go to config>main.php and uncomment

‘urlManager’=>array(
‘urlFormat’=>’path’,
‘rules’=>array(
‘<controller:\w+>/<id:\d+>’=>'<controller>/view’,
‘<controller:\w+>/<action:\w+>/<id:\d+>’=>'<controller>/<action>’,
‘<controller:\w+>/<action:\w+>’=>'<controller>/<action>’,
),
),

 

7. Passing variable data from controller to view

In Controller

public $message = ‘Hello World rom controller’;

public function actionIndex()
{
$this->render(‘index’,array(‘content’=>$this->message));
}

Now variable content is available to modified

In View

<?php echo $content ?>

Alternatively we could do

<?php echo $this->message   ?>

8. CRUD generation

a) Config database

b) Go to protected>>config>>main.php

c) Uncomment db componenent

d) Give the username , password, and db name

e) Comment out sqlite configuration which lie just above the mysql configuration

 

9. GO to gii

10. Select model generator

11. Enter table details and generate the model

12. We now have Message.php under model directory

13. Now click on CRUD generator

13. Enter Model name

14. Click generate

15. You can try it out by goign to baseurl/modelname

16. Access database content via these codes in controller

public $message = ”;

public function actionIndex()
{ $message=Message::model()->findByPK(3);
$this->message=$message->content;
$this->render(‘index’,array(‘content’=>$this->message));
}

Introduction to creating desktop applications with PHP and Titanium

Source: http://www.sanisoft.com/blog/2011/01/03/introduction-to-creating-desktop-applications-with-php-and-titanium/

Excerpts : 

What tools do you need ?

  • Download and install the Titanium DeveloperThe download and installation procedure has been discussed at length in the Titanium documentation in a simple and understandable way and even the steps on creating a new project and hence I am not putting the same here. I am assuming that you will download and comeback right here to know what next.
  • Text Editor with HTML / PHP syntax highlighting – If you are a web developer then you can’t be alive without one. Use your favorite.

On my Ubuntu 10.04 I got an error like : symbol lookup error: /usr/lib/lib-something: undefined symbol: something:

I did this to get rid of it :

– cd ~/.titanium/runtime/linux/1.0.0 if you install in your home dir.

or if you install in /opt/titanium/runtime/linux/1.0.0

– rm libgobject* libgthread* libglib* libgio*

Ready ?  What next ?

Follow http://www.sanisoft.com/blog/2011/01/03/introduction-to-creating-desktop-applications-with-php-and-titanium/ to read more

PHP Mysql notes

MYSQL

Index from : http://www.developphp.com/list_mysql.php

Connect to database script

$sqlCommand = “SELECT pagebody FROM pages WHERE id=’$pageid’ LIMIT 1”;
$query = mysqli_query($myConnection, $sqlCommand) or die (mysqli_error());
while ($row = mysqli_fetch_array($query)) {
$body = $row[“pagebody”];
}
mysqli_free_result($query);

 

Query the database 

 

PHP Crud

PHP CMS

PHP user authtication system

Django Deployment Guide For Ubuntu

Source:http://www.ventanazul.com/webzine/tutorials/django-deployment-guide-ubuntu

Ignite your Django projects with nginx, Apache and mod_wsgi

There’s a time when every Django developer has to think about deployment scenarios, when I first did it last year I thought that a setup involving Lighty, Apache, mod_proxy and mod_python was a good choice but my first approach was not the best. I put Apache as the front server, handling requests for Django generated pages and passing, via mod_proxy, requests for static content to Lighty on the back. A setup where Apache had to work even for files that wasn’t supposed to serve was a very bad idea.

After many helpful comments and some more reading I realized that it was better having the server for static content on the front and Apache, which still talks to Django, on the back.

I replaced Lighty with nginx, which according to many seems to be more stable, and opted for mod_wsgi instead of mod_python to make Apache talk to Django. mod_wsgi has a lower memory overhead and it’s suitable for high performance sites. There’s no need for mod_proxy on Apache anymore as nginx is the one in charge of the proxy work now.

This is an easy to follow and very focused guide for developers who know how to handle their servers so I won’t consider security issues, memcached, Django installation, databases or basic GNU/Linux, Apache and DNS settings. Of course all of those subjects are important and you should take care of them.

The plan

This guide includes all the steps needed to:

  • Setup a domain for your Django project.
  • Create a simple directory layout for Django sites.
  • Configure Apache with mod_wsgi for Django.
  • Configure nginx.
  • Serve Django admin media files.
  • Turn on the heat and show your greatest and latest Django stuff to the world.

After following all the steps you will have a Django site running with nginx on the front and Apache on the back. nginx will manage all static content and will pass Django requests to Apache and mod_wsgi.

I have tested on three Ubuntu servers (two running 8.10, Intrepid Ibex, and one 7.10, Gutsy Gibbon) but everything should be pretty similar in other GNU/Linux distributions.

Shall we start?

Setup a domain for your Django project

Many of us run more than one website in one server, I have several with Drupal and a few with Django living in one box, so let’s consider a two domains scenario: cataybea.com will host the Django project andexample.com anything else. Most of the work will focus in cataybea.com, I just mention example.com to give you some context. Obviously you should replace all the domain names in this guide with yours.

We’ll use a couple of private IP addresses for now and will replace them with public ones and setup in a DNS server when going live. For this guide I’ll just add to /etc/hosts, which is what I usually do in my development environment:

192.168.0.180 cataybea.com 192.168.0.192 example.com

I’m using 192.168.0.180 and two ports, 80 and 8080, for serving the Django site at cataybea.com. The default port 80 will be used by nginx to serve static content and Django will look for files under the /media directory. Port 8080 will be used by Apache to handle Django requests.

Create a simple directory layout for Django sites

Directory layouts depend on personal preferences, I currently use a /home/alexis/djcode directory for all my Django coding and the new project will be called cataybea; hence, we have to run:

mkdir /home/alexis/djcode cd /home/alexis/djcode/ django-admin.py startproject cataybea

Now let’s create some additional directories:

mkdir /home/alexis/djcode/cataybea/apache mkdir /home/alexis/djcode/cataybea/logs mkdir /home/alexis/djcode/cataybea/media

What are they for? apache will contain a Python script to setup mod_wsgi, logs will store Apache and nginx logs and media is the directory nginx will use to serve static files for our Django project.

You can later manage the whole /home/alexis/djcode/cataybea directory with your favorite version control tool.

Take note of the correct paths for using later in the configuration files.

Configure Apache with mod_wsgi for Django

I assume you already have Apache working correctly and just need to tweak a little for our Django setup. As we’ll be running two web servers at once we must make sure that IP addresses and ports won’t conflict. Let’s edit /etc/apache2/ports.conf:

Listen 192.168.0.192:80 Listen 192.168.0.180:8080 #Listen 80

I have specified IP addresses and ports to listen. Notice I commented the default Listen 80 as it means Apache would listen to that port in all IP addresses. If you want to use SSL take care of the 443 port in the same way.

If you are using virtual hosts in Apache confirm it’s listening to the correct IP addresses and ports, I have this in/etc/apache2/sites-enabled/example.com:

NameVirtualHost 192.168.0.192

Restart Apache and make sure your Apache sites work normally. I’m obsessed with testing at every step in the way and I suggest you are too.

sudo /etc/init.d/apache2 restart

Now it’s time to add mod_wsgi to Apache. The latest versions of Ubuntu have it in the repository:

sudo apt-get install libapache2-mod-wsgi

For older versions of Ubuntu, such as Gutsy, you need to find the .deb file and use something like dpkg -i to install.

Now it’s time to create the Apache configuration file for cataybea.com in /etc/apache2/sites-available/cataybea.com:

<VirtualHost 192.168.0.180:8080> ServerAdmin alexis@ventanazul.com ServerName http://www.cataybea.com ServerAlias cataybea.com <Directory /home/alexis/djcode/cataybea/apache/> Order deny,allow Allow from all </Directory> LogLevel warn ErrorLog /home/alexis/djcode/cataybea/logs/apache_error.log CustomLog /home/alexis/djcode/cataybea/logs/apache_access.log combined WSGIDaemonProcess cataybea.com user=www-data group=www-data threads=25 WSGIProcessGroup cataybea.com WSGIScriptAlias / /home/alexis/djcode/cataybea/apache/cataybea.wsgi </VirtualHost>

Notice the IP address and port: 192.168.0.180:8080. This site won’t be accessed directly but via proxy from nginx. We’ll set that up in the next section.

Now we need a Python script to configure our Django project to use mod_wsgi, create/home/alexis/djcode/cataybea/apache/cataybea.wsgi and put the following code inside:

import os, sys apache_configuration= os.path.dirname(__file__) project = os.path.dirname(apache_configuration) workspace = os.path.dirname(project) sys.path.append(workspace) sys.path.append(‘/usr/lib/python2.5/site-packages/django/’) sys.path.append(‘/home/alexis/djcode/cataybea’) os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘cataybea.settings’ import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()

Don’t restart Apache yet as we need to complete a few more steps.

Configure nginx

nginx will do two things: serve static content from http://cataybea.com/media and pass all other requests to Apache. Let’s install it first:

sudo apt-get install nginx

Now remove the nginx default site:

sudo rm /etc/nginx/sites-enabled/default

Apache and nginx should be using the same user, for Ubuntu this is www-data, and your /etc/nginx/nginx.confshould look like this:

user www-data; worker_processes 2; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; sendfile on; tcp_nopush on; keepalive_timeout 65; tcp_nodelay on; gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }

worker_processes can be set to the number of cores in your server, in my case that’s just 2.

Configure a the cataybea.com site on nginx by creating /etc/nginx/sites-available/cataybea.com:

server { listen 192.168.0.180:80; server_name http://www.cataybea.com cataybea.com; access_log /home/alexis/djcode/cataybea/logs/nginx_access.log; error_log /home/alexis/djcode/cataybea/logs/nginx_error.log; location / { proxy_pass http://192.168.0.180:8080; include /etc/nginx/proxy.conf; } location /media/ { root /home/alexis/djcode/cataybea/; } }

then running:

sudo ln -s /etc/nginx/sites-available/cataybea.com /etc/nginx/sites-enabled/cataybea.com

and finally creating the file that will take care of proxying Django requests to Apache, we’ll call it/etc/nginx/proxy.conf and put this inside:

proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;

Notice $host, $remote_addr and $proxy_add_x_forwarded_for are variables that will be handled by nginx, you don’t need to change anything else in proxy.conf for a basic setup. When I started playing with nginx I thought these had to be replaced by me, I was wrong.

Finally restart nginx:

sudo /etc/init.d/nginx restart

and Apache:

sudo /etc/init.d/apache2 restart

That should be it! If you visit http://cataybea.com you should see some Django content (could be the welcome page, some of your views or a 404 page depending on your project status). To try the nginx media server create a test.htm file with some dummy content in /home/alexis/djcode/cataybea/media and visithttp://cataybea.com/media/test.htm.

Serve Django admin media files (optional)

If you will use the Django admin application edit /home/alexis/djcode/cataybea/settings.py, make sure your database settings are correct, add ‘django.contrib.admin’ to the INSTALLED_APPS tuple and change theADMIN_MEDIA_PREFIX like this:

ADMIN_MEDIA_PREFIX = ‘/media/admin/’

Let’s enable the admin url by editing /home/alexis/djcode/cataybea/urls.py, uncommenting these two lines:

from django.contrib import admin admin.autodiscover()

and adding this to urlpatterns:

(r’^admin/’, include(admin.site.urls)),

Now let’s create a symbolic link to the media files for the Django’s administration section:

cd /home/alexis/djcode/cataybea/media ln -s /usr/lib/python2.5/site-packages/django/contrib/admin/media/ admin

And finally let’s create the administration user and the required tables in the database:

cd /home/alexis/djcode/cataybea/media python manage.py syncdb

As with every other modifications in your Django code you will have to reload Apache for changes to take effect:

sudo /etc/init.d/apache2 reload

Visit http://cataybea.com/admin/,including the trailing slash, and you should be in business.

Setup Samba peer-to-peer with Windows

As many fellow Ubuntu users seem to have trouble setting up samba peer-to-peer with Windows I decided to write a small howto on this matter.

NOTE: I am aware that there’s a wiki-page as well as several other howto’s around – but by looking at the constant “how do I setup samba” posts that are floating around in the forum I simply see the need for a more thourough guide on this matter.

Feel free to contribute and suggest – it’ll only help to make this howto a better guide.

The goal of this howto is to have samba act like a Windows Workstation in the LAN. As a “value added bonus” we will use samba to do netbios name resolution so that you can use the names of the workstations for network drive mapping instead of their ip-addresses (i.e.: \MY_WINDOWS_BOX\SHARE) – but only for as long as your Linux box has an static ip-address and is up and running.

This guide is based on Ubuntu 6.06 LTS and intended for all architectures (i386, AMD64, …) – if you are still using Breezy it’s safe to follow this guide as there should be no differencies.

A second guide on how to setup samba as Primary Domain Controller along with several other services such as DHCP, DNS and NTP will follow later on as this topic will be a little more thourough.

1. Prerequisites

– Your Linux box should have an static ip-address.
In case you’re getting your ip from a router/server via DHCP make sure it’s configured to provide a fixed dhcp-lease. If that’s no valid option you cannot use WINS … more on this way down.

– You need to have samba installed.
If you haven’t done so already open a terminal and type:

Code:
sudo apt-get install samba

Don’t close the terminal upon installation – we still need the commandline to get several tasks done!

2. Getting samba configured

First, let us make sure samba isn’t running:

Code:
sudo /etc/init.d/samba stop

As a starting point I included an smb.conf below, and there are only a few simple things you may need to tweak.

Since the installation of samba just installed a rather useless template file we’re going to rename it – we keep the file just in case.

Code:
sudo mv /etc/samba/smb.conf /etc/samba/smb.conf.template

Next we create a new empty file

Code:
sudo touch /etc/samba/smb.conf

And finally we need to open the file inside an editor

Code:
sudo gedit /etc/samba/smb.conf

NOTE: If you’re on KDE replace “gedit” with “kate”

Copy / Paste the contents of the code-section below into your editor and read on …

Code:
[global]
    ; General server settings
    netbios name = YOUR_HOSTNAME
    server string =
    workgroup = YOUR_WORKGROUP
    announce version = 5.0
    socket options = TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192

    passdb backend = tdbsam
    security = user
    null passwords = true
    username map = /etc/samba/smbusers
    name resolve order = hosts wins bcast

    wins support = yes

    printing = CUPS
    printcap name = CUPS

    syslog = 1
    syslog only = yes

; NOTE: If you need access to the user home directories uncomment the
; lines below and adjust the settings to your hearts content.
;[homes]
    ;valid users = %S
    ;create mode = 0600
    ;directory mode = 0755
    ;browseable = no
    ;read only = no
    ;veto files = /*.{*}/.*/mail/bin/

; NOTE: Only needed if you run samba as a primary domain controller.
; Not needed as this config doesn't cover that matter.
;[netlogon]
    ;path = /var/lib/samba/netlogon
    ;admin users = Administrator
    ;valid users = %U
    ;read only = no

; NOTE: Again - only needed if you're running a primary domain controller.
;[Profiles]
    ;path = /var/lib/samba/profiles
    ;valid users = %U
    ;create mode = 0600
    ;directory mode = 0700
    ;writeable = yes
    ;browseable = no

; NOTE: Inside this place you may build a printer driver repository for
; Windows - I'll cover this topic in another HOWTO.
[print$]
    path = /var/lib/samba/printers
    browseable = yes
    guest ok = yes
    read only = yes
    write list = root
    create mask = 0664
    directory mask = 0775

[printers]
    path = /tmp
    printable = yes
    guest ok = yes
    browseable = no

; Uncomment if you need to share your CD-/DVD-ROM Drive
;[DVD-ROM Drive]
    ;path = /media/cdrom
    ;browseable = yes
    ;read only = yes
    ;guest ok = yes

[MyFiles]
    path = /media/samba/
    browseable = yes
    read only = no
    guest ok = no
    create mask = 0644
    directory mask = 0755
    force user = YOUR_USERNAME
    force group = YOUR_USERGROUP

Ok, I already mentioned that there are a few simple things you may need to tweak; so here they are:

-> netbios name = YOUR_HOSTNAME

Replace “YOUR_HOSTNAME” with your desired hostname (don’t use spaces!). Best pratice would be to use the same name you configured upon installation.

Example:

netbios name = DAPPER

-> workgroup = YOUR_WORKGROUP

Replace “YOUR_WORKGROUP” with the name of your workgroup, but make sure you’re using the same as configured in Windows.

To find out the Workgroup name in Windows follow these steps:

– Click “START”
– Click “Control Panel”
– Click “System”
– Click the 2nd Tab entitled “Computername” and find the name of the Workgroup there.

Example:

workgroup = MSHOME

-> wins support = yes

If your box doesn’t have a static ip-address, or you cannot configure your router/server to provide you with a fixed dhcp-lease, change this configuration parameter to “no”.

In this case you cannot use the benefits of WINS.

-> [MyFiles]

This is the name of the share. Leave it as it is or adjust it to whatever you prefer. Don’t use more than 31 characters and try to avoid spaces!

-> path = /media/samba/

This suggests that you’ve mounted an hard drive or partition on /media/samba where all the shared files will be stored.

In case you don’t have an extra hard drive/partition you may also create folder.

I assume you’ve been wise enough to put /home onto a separate partition having an reasonable amount of storage space.

To create the folder type (inside a new terminal) …

Code:
sudo mkdir /home/samba

… and adjust “path =” to read …

path = /home/samba/

Remember that this is just an example – you are free to put things wherever you like.

-> force user = YOUR_USERNAME
-> force group = YOUR_USERNAME

Well, this should say it all. Replace “YOUR_USERNAME” with the name you use for login (no spaces!).

Example:

force user = stormbringer
force group = stormbringer

Now we completed the part of editing smb.conf

Save the file and close gedit.

Since we are going to share the folder with other users we should now make sure that the permissions are set. Type:

Code:
sudo chmod 0777 /media/samba

NOTE: Don’t forget to correct the path to the location you chose above!

That’s it – now we need to start samba …

1.1 Starting samba and setting up user accounts

Let us fire up samba for the first time. Type:

Code:
sudo /etc/init.d/samba start

There shouldn’t be any errors – if you are presented with an error message make sure everything is correct (search for typos and/or invalid paths).

Time to add yourself as an samba user.

NOTE: You will be asked for a password – make sure you use the same as you use for login!

Code:
sudo smbpasswd -L -a your_username
sudo smbpasswd -L -e your_username

In case you need other users to be able to access the share you need to add them to your system AND samba as well. Make sure you use the very same Windows usernames and passwords!

NOTE: Windows XP doesn’t set passwords for its useraccount per default. If you haven’t set a password on your XP box just press enter when prompted to enter a password for the user account you’re about to create!

In the following example we will add an user called “mark” …

Example:

Code:
sudo useradd -s /bin/true mark
sudo smbpasswd -L -a mark
sudo smbpasswd -L -e mark

The “-s /bin/true” in the first line prevents the users from being able to access the commandline of your linux box (“-s” stands for “shell”). I strongly advise you to follow this recommendation! Don’t change that setting to a valid login-shell unless you really know what you are doing!

Repeat this step until you configured all user accounts!

Now that we configured samba and created the user accounts we are done with the Linux-part – there’s one more thing to do in Windows.

2. Changing network settings in Windows

Now we should let Windows know that there’s a WINS server active in the network.

If you had to change “wins support” to “no” above skip this step!

– Click “START”
– Click “Control Panel”
– Click “Network Connections”
– Find your “LAN Connection”
– Right-click the icon and select “Properties”
– Select the “TCP/IP” Protocol and click the “Properties” button
– Click “Advanced”
– Select the third Tab entitled “WINS”
– Click “Add”
– Type in the ip-address of your Linux box
– Click “Add”
– Select “Use NetBIOS over TCP/IP”
– Click “OK”
– Click “OK”
– Click “OK”
– Reboot Windows

Upon reboot you may now map the network drive within Windows.

With WINS enabled:
– Click “START”
– Right-click “My Computer”
– Select “Map network drive”
– Choose the drive letter
– Type \\DAPPER\MyFiles
NOTE: Adjust this to the hostname and sharename you chose above!
– Click “Finish”

With WINS disabled:
– Click “START”
– Right-click “My Computer”
– Select “Map network drive”
– Choose the drive letter
– Type \\<ip-address>\MyFiles
NOTE: To find out the ip-address of your Linux box type “ifconfig” inside a terminal and find the ip for the correct interface (i.e. eth0). Don’t forget to adjust the sharename to the name you chose above.
– Click “Finish”

That’s it – samba is up and running now.

3. Security consideration

This is the right time to think about security right away.

In case your computer has more than one network connection (i.e. wired and wireless ethernet) you may want to restrict access to samba.

If not especially configured samba will bind its service to all available network interfaces.

So, let us assume you only want your wired network to have access and that the network card is called eth0.

Add the following lines to the [general] section of your smb.conf to achieve that goal:

Code:
interfaces = lo, eth0
bind interfaces only = true

If you did it correctly it should look similar to this:

Code:
[global]
    ; General server settings
    netbios name = YOUR_HOSTNAME
    server string =
    workgroup = YOUR_WORKGROUP
    announce version = 5.0
    socket options = TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192
    interfaces = lo, eth0
    bind interfaces only = true

Now only the local loopback interface (dubbed “lo”) and eth0 are able to access samba – there’s no need to fear that someone might break into your system by wireless as the interface isn’t bound to the service.

4. Final words

If you happen to have any questions feel free to ask – I’ll try to help as soon as possible.

If you find any mistakes in this howto please let me know so that I can fix them.

Feel free to contribute and suggest – help to make this howto a better guide.

5. Addendum: Useful links

Here are some links you may find useful.

The onsite links refer to other samba-guides and to ubuntu_daemon’s “Important Links” thread.

– Onsite
Ubuntu Help: Windows Networkworking
Ubuntu Documentation: Setting up Samba

READ THIS FIRST prior to posting – IMPORTANT links (by ubuntu_daemon)

The offsite links refer to the offical Samba homepage and to a selected choice of their official documentation; these links are useful if you like to dig yourself into the mysteries of samba’s configuration and usage as well as troubleshooting problems.

– Offsite
Samba Homepage

Practical Exercises in Successful Samba Deployment
The Official Samba-3 HOWTO and Reference Guide
Using Samba, 2nd Edition

%d bloggers like this: