• Tidak ada hasil yang ditemukan

BAB III. ANALISA DAN DESAIN

3.2. Perancangan Data

Untuk melakukan initialisasi terhadap socket, perlu dibuat sebuah input data sebagai masukan dari user.

Data keterangan

Config_dir Untuk meletakkan configurasi directory

Perldef Memberikan keterangan tentang letak directory perl

Real_os_type Nama sistem operasi

Real_os_version Versi sistem operasi

Port Nomer port yang digunakan

Login Input data login

Passw Input data password

Host Nama host

Tabel 3.1. Tabel data Initialisasi

Untuk melakukan penyuntingan terhadap user administrator maka dibutuhkan data-data yang berisi user administrator, password dan hak akses. Data tersebut merupakan konfigurasi dari pengguna program admin yang pertama kali.

Perlu untuk dimasukkan pada saat initialisasi karena untuk menggunakan program ini paling sedikit harus ada satu user.

Data Keterangan

Mods Daftar modul/Task

Ulist Daftar user dari pwfile

PWFILE File berisi user password

Tabel 3.2. Tabel data user administrator

Pada module Schedule Cron Job dibutuhkan data-data yang akan digunakan

untuk menampilkan seluruh cronjob yang terdapat dalam sistem.

Data Keterangan

TAB Daftar seluruh cron job yang dimiliki oleh user

Jlist Daftar seluruh cron job beserta user name dan perintahnya

cron_allow_file Daftar user diterima (allowed)

cron_deny_file Daftar user ditolak (denied)

Tabel 3.3. data Cron job

Modul export membutuhkan data yang berisi seluruh export file atau directory yang ada di dalam sistem untuk digunakan sebagai input untuk proses

editing export.

Data Keterangan

Exp Berisi daftar export

Tabel 3.4. data export

Pada tabel 3.5 merupakan data-data yang akan berfungsi untuk menyimpan informasi tentang protocol dan service yang terdapat di dalam sistem.

Data Keterangan

Config{service_file} Konfigurasi services dari service file

Config{Inetd_conf_file} Berisi configurasi internet service

Config{protocol_file} Berisi daftar protocols dalam sistem

SERVICES Daftar service

Tabel 3.5. Data service & protocol

Pada modul printer administration diperlukan tempat untuk menyimpan data-data yang akan digunakan untuk proses edit, delete, maupun create.

Data Keterangan

Prn Menampung nama printer

Jobs Daftar printer Jobs

CAP File princap

Plist Daftar semua printer

Tabel 3.6. Data printer

Untuk menunjukkan status file-file maupun direktori tertentu dapat menggunakan data-data seperti di bawah ini untuk menyimpan informasi dari sistem tentang status file maupun direktori yang ada dalam sistem.

Data Keterangan

MTAB Daftar mount (/etc/mtab)

FSTAB Daftar filesystem saat booting (/etc/fstab)

Tabel 3.7. Data Mount

Berikut adalah data-data yang diambil dari sistem yang akan digunakan untuk administrasi dan konfigurasi network .

Data Keterangan

HOTS Daftar hosts dan alamat

IFC Daftar Interface

RESOLV Konfigurasi dns

STATIC Konfigurasi rute statis

Tabel 3.8. Data Network

Untuk melakukan proses administrasi terhadap unix/linux user dibutuhkan informasi tentang user, group dan password. Untuk menyimpan informasi tersebut dibutuhkan data seperti daftar linux user maupun daftar group user.

Data Keterangan

Passwd Daftar linux user

Group Daftar linux group

Pam Daftar Password acak

Base uid UID untuk user

Base gid GID untuk group

Tabel 3.9. Data Linux user

3.3. Perancangan Proses.

Sebelum melakukan proses pengiriman dan penerimaan data (HTTP

Interactions), terlebih dahulu dilakukan proses membuka socket. Socket dapat

diibaratkan sebagai chanel pada sebuah radio yang mempunyai

gelombang-gelombang tertentu dalam proses pengiriman dan penerimaan data. Apabila sebuah socket dibuka dengan “gelombang” tertentu, maka hanya komputer dengan “gelombang” yang sama yang dapat menerima data yang dikirim. Setelah socket dibuka, maka dialokasikan alamat protokol lokal ke dalamnya. Alamat protokol terdiri dari kombinasi 32-bit sampai dengan 128-bit alamat internet (IP Address) ditambah dengan 16-bit nomor port pada protokol TCP dan UDP. Proses

pengalokasian alamat protokol disebut proses BIND. Socket yang telah diaktifkan

dan dialokasikan kemudian bersiap untuk merima data yang dikirim oleh komputer lain (listen). Pada server, proses ini digunakan untuk menunggu koneksi dari client. Setiap koneksi ditampung dalam satu antrian dan secara otomatis server akan mengatur koneksi-koneksi tersebut serta memilih koneksi mana yang benar-benar komplit dan siap untuk ditanggani (accept). Client yang sudah terkoneksi dapat melakukan proses pengiriman dan penerimaan data antar client-client yang lain.

Server akan menunggu koneksi terhadap network pada port, ketika client terhubung dengan port, server akan menerima koneksi tersebut dan kemudian akan berhubungan dengan client dengan menggunakan protocol yang mereka sepakati (tcp, http, nntp, smtp, dll).

Server akan menggunakan socket() system call untuk menciptakan socket,

dan bind() call akan menugaskan socket pada port tertentu pada host. Server

kemudian akan menggunakan rutin listen() dan accept() untuk menciptakan

komunikasi pada port. Pada sisi yang lain client juga menggunakan socket() system

call to create socket dan kemudian akan menggunakan connect() call untuk

inisialisasi koneksi yang berasosiasi dengan socket pada remote host tertentu dan

port. Server menggunakan accept() call untuk menerima koneksi yang datang dan inisialisasi komunikasi dengan client. Client dan server akan menggunakan

sysread() dan syswrite() untuk berkomunikasi pada HTTP sampai transaksi selesai. Apabila transaksi telah selesai maka baik client maupun server akan menggunakan

close() atau shutdown() untuk mengakhiri koneksi. Proses-proses yang terjadi diatas akan dijelaskan dalam sebagai berikut:

3.3.1. Proses transaksi http.

Sebelum memasuki proses penerimaan dan pengiriman data yang merupakan inti dari sistem aplikasi ini, diperlukan beberapa deklarasi awal yang berlaku secara global atau menyeluruh disemua proses-proses yang ada didalam sistem. Setelah itu dilakukan inisialisasi terhadap proses dan prosedur yang telah dibuat tersebut sebagai tanda dimulainya proses pengiriman dan penerimaan data.

Salah satu deklarasi yang perlu didefinisikan adalah terlebih dahulu adalah

socket. Function dari pendeklarasian tersebut adalah sebagai berikut :

$perl -e 'use Socket; socket(FOO, PF_INET, SOCK_STREAM,

getprotobyname("tcp")); setsockopt(FOO, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)); bind(FOO, sockaddr_in($ARGV[0], INADDR_ANY)) || exit(1); exit(0);' $port

if [ $? != "0" ]; then

echo "ERROR: TCP port $port is already in use by another program" echo ""

exit 13

Baik client dan server keduanya sama-sama menggunakan fungsi socket()

untuk menciptakan I/O buffer dalam sistem operasi. Socket() memerlukan

beberapa argumen yang berupa file handle yang berasosiasi dengan socket,

network protocol, dan bagaimana tipe socket, stream-oriented atau

record-oriented. Untuk transaksi HTTP, tipe socket yang digunakan adalah tipe stream-oriented. Dalam contoh berikut di bawah ini, file handle SH berasosiasi dengan

socket yang baru diciptakan. PF_INET adalah indikasi dari internet protocol,

sedangkan getprotobyname('tcp') merupakan indikasi dari Transmission Control

Protocol (TCP), sedangkan SOCK_STREAM adalah indikasi dari tipe socket stream-oriented. Bila socket calls gagal maka program akan die() menggunakan

pesan kesalahan (error message) yang terdapat dalam $!. Di bawah adalah

berbagai macam variasi yang biasa digunakan untuk melalukan insialisasi socket: socket(SH, PF_INET, SOCK_STREAM, getprotobyname("tcp")) || $!;

$proto = getprotobyname('tcp');

socket(MAIN, PF_INET, SOCK_STREAM, $proto) || die "Failed to open main socket : $!";

socket($h, PF_INET, SOCK_STREAM, getprotobyname("tcp")) || &error("Failed to create socket : $!");

Kemudian socket diinisialisasi (dibuka) sesuai dengan jenis protocol yang digunakan. Berikut ini adalah inisialisasi socket dengan menggunakan protocol TCP secara lengkap.

# Open main socket {miniserv.pl}

$proto = getprotobyname('tcp');

socket(MAIN, PF_INET, SOCK_STREAM, $proto) || die "Failed to open main socket : $!";

setsockopt(MAIN, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)); $baddr = $config{"bind"} ? inet_aton($config{"bind"}) : INADDR_ANY; bind(MAIN, sockaddr_in($config{port}, $baddr)) ||

die "Failed to bind port $config{port} : $!"; listen(MAIN, SOMAXCONN);

# Read the HTTP request and headers ($reqline = &read_line()) =~ s/\r|\n//g;

if (!($reqline =~ /^(GET|POST)\s+(.*)\s+HTTP\/1\..$/)) { &http_error(400, "Bad Request");

}

$method = $1; $request_uri = $page = $2; %header = ();

while(1) {

($headline = &read_line()) =~ s/\r|\n//g; if ($headline eq "") { last; }

($headline =~ /^(\S+):\s+(.*)$/) || &http_error(400, "Bad Header"); $header{lc($1)} = $2;

}

if (defined($header{'host'})) {

if ($header{'host'} =~ /^([^:]+):([0-9]+)$/) { $host = $1; } else { $host = $header{'host'}; }

}

if ($page =~ /^([^\?]+)\?(.*)$/) {

# There is some query string information $page = $1; $querystring = $2; if ($querystring !~ /=/) { $queryargs = $querystring; $queryargs =~ s/\+/ /g; $queryargs =~ s/%(..)/pack("c",hex($1))/ge;

$querystring = ""; }

}

b. Membuat koneksi network

Dengan mengunakan fungsi connect() dapat dibuat sebuah hubungan dengan

server dalam sebuah network (network connections) berikut host dan port yang

dikehendaki, dan menyelaraskan (associate) dengan I/O buffer yang telah

diciptakan oleh socket().

$sin = sockaddr_in (80, inet_aton, (‘localhost.localdomain.com’)); connect(SH,$sin) || die $!;

Rutin sockaddr_in() menerima sebuah port number sebagai parameter

pertama dan IP address sebaggai parameter kedua. Inet_aton() menerjemahkan

(translates) sebuah hostname string atau sebuah dotted decimal string menjadi

sebuah IP address 32-bit. sockaddr_in mengembalikan struktur data yang datang

melalui fungsi connect(), dari sanalah connect() mampu melakukan proses

koneksi pada sebuah jaringan komputer pada server dan port secara spesifik.

Berikut adalah penerapan fungsi connect() pada aplikasi:

($addr = inet_aton($_[0])) ||

&error("Failed to lookup IP address for $_[0]"); connect($h, sockaddr_in($_[1], $addr)) ||

&error("Failed to connect to $_[0]:$_[1] : $!");

Apabila koneksi terhadap network tersebut sukses, maka nilai yang kembali

adalah true, namun apabila gagal maka nilai false akan diberikan, untuk

setelah connect() untuk menghentikan program dan melaporkan kesalahan.

Fungsi connect() ini hanya dapat digunakan oleh client saja.

# open_socket(host, port, handle) <weblib.pl> sub open_socket

{

local($addr, $h); $h = $_[2];

socket($h, PF_INET, SOCK_STREAM, getprotobyname("tcp")) || &error("Failed to create socket : $!");

($addr = inet_aton($_[0])) ||

&error("Failed to lookup IP address for $_[0]"); connect($h, sockaddr_in($_[1], $addr)) ||

&error("Failed to connect to $_[0]:$_[1] : $!"); select($h); $| =1; select(STDOUT);

}

c. Menulis data pada koneksi network

Untuk menulis file handle (data) yang berasosiasi dengan socket (network

connection), dapat digunakan rutin syswrite(). Parameter pertama merupakan file

handle untuk menulis data, sedang data yang akan ditulis dijadikan parameter kedua. Sedangkan parameter ketiga adalah panjang data yang akan ditulis.

Syswrite() digunakan oleh client dan server. $buffer = ”Linux Web Administration”;

syswrite (FH, $buffer, length($buffer)); # sysprint(handle, [string]+) sub sysprint { local($str, $fh); $str = join('', @_[1..$#_]); $fh = $_[0]; syswrite $fh, $str, length($str); }

Untuk membaca data dari sebuah koneksi network dapat digunakan rutin

sysread() fungsi tersebut dapat berjalan baik pada server maupun client sysread()

membaca data dari file handle yang berasosiasi dengan socket tersebut, pada

parameter pertama file handle diberikan untuk menerangkan koneksi yang akan dibaca. Sedangkan parameter kedua menunjukkan sebuah variabel scalar untuk menyimpan data yang telah dibaca. Parameter ketiga menunjukkan bytes maksimum yang akan dibaca dari sebuah koneksi.

Sysread(FH, $buffer, 200); # read at most 200 bytes from FH $buffer = <FH>;

e. Mengakhiri Koneksi

Setelah transaksi selesai (complete), rutin close() akan mengakhiri koneksi

jaringan (closing network connections). Fungsi ini dapat digunakan baik oleh

client maupun server. close(FH);

f. Mendengarkan port

Fungsi bind() digunakan hanya oleh server. Rutin bind() menyelaraskan

(associate) antara socket buffer dengan port pada perangkat keras (computer).

Apabila port yang dimaksud telah digunakan oleh program lain maka bind() akan

memberikan nilai false (zero). Sockaddr_in() dapat digunakan untuk identifikasi

atau mengenali port untuk bind(). Definisi port dapat berupa variabel dapat juga

ditulis secara langsung. Proses ini dikenal dengan Binding the Port.

bind(MAIN, sockaddr_in($config{port}, $baddr)) || die "Failed to bind port $config{port} : $!";

Socket yang telah diinisialisasi atau diaktifkan, menandai dibukanya jalur akses ke alamat lokal protokol. Oleh karena itu diperlukan proses untuk memasuki jalur yang telah disediakan oleh socket tersebut.

Fungsi bind akan sukses atau berhasil dijalankan jika nilai yang dihasilkan berupa 0 (null) dan bernilai –1 (socket_error) jika tidak berjalan semestinya. Proses bind akan menspesifikasikan alamat lokal dan port yangg sudah didefinisikan sebelumnya. Alamat lokal yang tidak didefinisikan secara jelas (inaddr_any), akan menonaktifkan sistem untuk memilih alamat lokal sampai adanya koneksi dari socket yang lain. Dengan demikian default alamat lokal dengan INADDR_ANY sangat effisien dipakai diawal pertama kali socket diaktifkan.

g. Menunggu koneksi

Fungsi listen() hanya digunakan oleh server untuk menunggu datangnya

koneksi dari client. Fungsi listen() memberitahukan pada sistem operasi bahwa

server siap untuk menerima koneksi jaringan yang akan masuk pada port yang telah ditentukan. Parameter pertama merupakan file handle pada socket untuk melakukan proses listen.

listen(MAIN, SOMAXCONN);

h. Menerima Koneksi

menerima datangnya koneksi dari client. Dengan kata lain Accept() berfungsi

untuk menunggu datangnya permintaan (request) pada server. Untuk parameter

accept() menggunakan dua file handle, satu berassosiasi dengan socket sedang

yang lain berassosiasi dengan koneksi network tertentu (specifik network

connections).

# got new connection

$acptaddr = accept(SOCK, MAIN); if (!$acptaddr) { next; }

Proses yang terjadi pada program aplikasi ini akan dikelompokkan berdasar fungsi-fungsi yang ada dalam program aplikasi.

i. Proses penerimaan data

Pada saat data yang diminta dikirim segera dijalankan proses penerimaan data. Proses ini merupakan tahap dari sistem untuk menerima koneksi dari socket lain. Setelah alamat dan port sudah teralokasikan melalui proses bind, dapat diartikan bahwa socket telah diaktifkan untuk menerima koneksi dari socket lain serta membuka jalur bagi data-data yang akan memasuki sistem (receive).

# read_line()

# Reads one line from SOCK sub read_line

{

local($idx, $more, $rv); if ($use_ssl) {

while(($idx = index($read_buffer, "\n")) < 0) { # need to read more..

if (!($more = Net::SSLeay::read($ssl_con))) { # end of the data

$rv = $read_buffer; undef($read_buffer); return $rv;

}

$read_buffer .= $more; }

$rv = substr($read_buffer, 0, $idx+1);

$read_buffer = substr($read_buffer, $idx+1); return $rv;

}

else { return <SOCK>; } }

Fungsi receive form berfungsi sebagai jalur pembuka yang selalu siap menangani setiap socket yang berinteraksi.

j. Proses pengiriman data

Proses listen atau proses penerimaan data diulang secara terus menerus agar sistem selalu siap menerima semua paket data yang yang ditujukan ke alamat sistem. Proses penerimaan data sistem bersifat pasif yaitu menunggu datangnya

data sehingga sistem harus selalu stand by.

# write_data(data)

# Writes a string to SOCK sub write_data { if ($use_ssl) { Net::SSLeay::write($ssl_con, $_[0]); } else { print SOCK $_[0]; } $write_data_count += length($_[0]); }

3.3.2. Proses dalam Modul

Proses modul adalah proses pasif, artinya proses tersebut tidak akan dijalankan apabila tidak ada perintah dari user, meskipun user telah terlebih dahulu

mengaktifkan proses transaksi http.

a. Admin Users

Admin user adalah sebuah tools untuk membuat, edit, menghapus, user administrator, atau orang-orang yang memiliki hak untuk melakukan proses administrasi dengan menggunakan program aplikasi ini. Dalam tools ini seorang administrator dapat mengatur fasilitas-fasilitas mana saja yang diperkenankan untuk dipakai oleh setiap user administrator.

Untuk menampilkan data-data user yang berhak untuk menggunakan program admin dibuat subrutin yang berfungsi untuk mengambil data user yang berada dalam /etc/admin. Data tersebut kemudian ditempatkan dalam sebuah file handle bernama PWFILE. PWFILE akan disimpan dalam array untuk ditampilkan pada form yang disediakan.

sub list_users {

local(@mods, %miniserv, $_, @rv, %acl); &read_acl(undef, \%acl); @mods = &list_modules(); &get_miniserv_config(\%miniserv); open(PWFILE, $miniserv{'userfile'}); while(<PWFILE>) { if (/^([^:\s]+):([^:\s]+)(:(\d+))?/) { local(%user); $user{'name'} = $1; $user{'pass'} = $2; $user{'sync'} = $4 if ($3); $user{'modules'} = $acl{$1}; push(@rv, \%user); } } close(PWFILE);

Untuk menciptakan user baru bagi administrator maka perlu membuka file handle PWFILE. Program admin akan menerima input dari user, kemudian akan menjalan subrutin create_user yang akan menambahkan input dari user untuk disimpan dalam /etc/admin.

# create_user(&details) sub create_user

{

local(%user, %miniserv, @mods); %user = %{$_[0]};

&get_miniserv_config(\%miniserv);

open(PWFILE, ">> $miniserv{'userfile'}");

print PWFILE "$user{'name'}:$user{'pass'}:$user{'sync'}\n"; close(PWFILE);

Sama dengan ketika membuat user baru, untuk merubah user data-data tentang user perlu ditampilkan terlebih dahulu, user akan menekan tombol save apabila telah selesai melakukan perubahan. Ketika tombol save ditekan maka subrutin modify user akan dijalankan. File handle PWFILE yang menyimpan data user akan ditulis kembali menggantikan data yang lama.

# modify_user(name, &details) sub modify_user

{

local(%user, %miniserv, @pwfile, @acl, @mods, $_, $m); %user = %{$_[1]}; &get_miniserv_config(\%miniserv); open(PWFILE, $miniserv{'userfile'}); @pwfile = <PWFILE>; close(PWFILE); open(PWFILE, "> $miniserv{'userfile'}"); foreach (@pwfile) { if (/^([^:\s]+):([^:\s]+)/ && $1 eq $_[0]) {

print PWFILE "$user{'name'}:$user{'pass'}:$user{'sync'}\n"; }

}

close(PWFILE);

Data user masih harus ditampilkan apabila hendak menghapus user yang telah ada. Input dari user yang berupa penekanan tombol delete akan menjalankan subrutin delete_user. Data yang tersimpan dalam PWFILE akan disimpan kembali menggantikan data sebelumnya.

# delete_user(name){func del_usr-/acl/acl-lib.pl} sub delete_user

{

local($_, @pwfile, @acl, %miniserv); &get_miniserv_config(\%miniserv); open(PWFILE, $miniserv{'userfile'}); @pwfile = <PWFILE>; close(PWFILE); open(PWFILE, "> $miniserv{'userfile'}"); foreach (@pwfile) { if (!/^([^:\s]+):([^:\s]+)/ || $1 ne $_[0]) { print PWFILE $_; } } close(PWFILE);

Apabila ada kegagalan dalam proses penghapusan user maka error message dapat ditampilkan dalam $whatfailed.

# modify_user(name, &details){func edt_usr-/acl-lib.pl} sub modify_user

{

local(%user, %miniserv, @pwfile, @acl, @mods, $_, $m); %user = %{$_[1]}; &get_miniserv_config(\%miniserv); open(PWFILE, $miniserv{'userfile'}); @pwfile = <PWFILE>; close(PWFILE); open(PWFILE, "> $miniserv{'userfile'}"); foreach (@pwfile) {

if (/^([^:\s]+):([^:\s]+)/ && $1 eq $_[0]) {

print PWFILE "$user{'name'}:$user{'pass'}:$user{'sync'}\n"; }

else { print PWFILE $_; } }

close(PWFILE);

b. Linux Users

Linux user adalah modul yang mengatur administrasi terhadap user-user linux. Dalam modul ini seorang administrator mampu untuk membuat user baru,

menghapus user, atau melakukan proses editing terhadap account seorang user.

Untuk keperluan tersebut diperlukan sebuah fungsi yang dapat mencari acount dari linux user. Berikut adalah fungsi untuk mengetahui user-user yang memiliki hak untuk menggunakan linux.

# password_file(file){user-lib.pl} sub password_file { if (!$_[0]) { return 0; } elsif (open(SHTEST, $_[0])) { local($line); $line = <SHTEST>; close(SHTEST); return $line =~ /^\S+:\S*:/; } else { return 0; } } # list_users() sub list_users {

# read the password file . . .

# start by reading /etc/passwd $lnum = 0;

open(PASSWD, $config{'passwd_file'}); while(<PASSWD>) {

s/\r|\n//g;

if (/\S/ && !/^[#\+\-]/) {

@pw = split(/:/, $_, -1);

push(@rv, { 'user' => $pw[0], 'pass' => $pw[1],

'uid' => $pw[2], 'gid' => $pw[3],

'real' => $pw[4], 'home' => $pw[5],

'shell' => $pw[6], 'line' => $lnum, 'num' => scalar(@rv) }); $idx{$pw[0]} = $rv[$#rv]; } $lnum++; } close(PASSWD);

Fungsi ini mencari file yang berada pada lokasi /etc/passwd, yaitu lokasi untuk menyimpan data-data password dari linux user. Data-data ini kemudian

dibaca dan disimpan dalam hashtable array bernama PASSWD, dari data ini

akan diperoleh informasi tentang user, pass, uid, gid, real, home, shell karena setiap file yang diambil mengandung informasi tersebut untuk masing-masing user.

Pada prinsipnya untuk membuat user baru, dapat ditambahkan pada daftar user yang disimpan dalam passwd, untuk selanjutnya disimpan kembali dalam direktory /etc/passwd.

sub crete_user < Creates a new user with the given details >

{

local(%u) = %{$_[0]}; if (&passfiles_type() == 1) {

# just need to add to master.passwd

open(PASSWD, ">> $config{'master_file'}"); print PASSWD "$u{'user'}:$u{'pass'}:$u{'uid'}:$u{'gid'}:$u{'class'}:$u{'change'}:$u{'expire'}:$ u{'real'}:$u{'home'}:$u{'shell'}\n"; close(PASSWD); }

else {

# add to /etc/passwd

open(PASSWD, ">> $config{'passwd_file'}");

print PASSWD "$u{'user'}:",&passfiles_type() == 2 ? "x" : $u{'pass'}, ":$u{'uid'}:$u{'gid'}:$u{'real'}:$u{'home'}:$u{'shell'}\n"; close(PASSWD);

if (&passfiles_type() == 2) { # add to shadow as well..

open(SHADOW, ">> $config{'shadow_file'}"); print SHADOW "$u{'user'}:$u{'pass'}:$u{'change'}:$u{'min'}:$u{'max'}:$u{'warn'}:$u{'inactive' }:$u{'expire'}:\n"; close(SHADOW); } } }

Hal yang sama terjadi juga terhadap fungsi modify user. Data-data dapat diambil dari passwd, kemudian merubah data tersebut dan menyimpannya kembali dalam lokasi yang sama.

# modify_user(&old, &details) sub modify_user { local(%u) = %{$_[1]}; local(@passwd, @shadow); if (&passfiles_type() == 1) {

# just need to update master.passwd

&replace_file_line($config{'master_file'}, $_[0]->{'line'}, "$u{'user'}:$u{'pass'}:$u{'uid'}:$u{'gid'}:$u{'class'}:". "$u{'change'}:$u{'expire'}:$u{'real'}:$u{'home'}:$u{'shell'}\n"); } else { # update /etc/passwd &replace_file_line($config{'passwd_file'}, $_[0]->{'line'}, "$u{'user'}:".(&passfiles_type() == 2 ? "x" : $u{'pass'}). ":$u{'uid'}:$u{'gid'}:$u{'real'}:$u{'home'}:$u{'shell'}\n"); if (&passfiles_type() == 2) {

&replace_file_line($config{'shadow_file'}, $_[0]->{'sline'}, "$u{'user'}:$u{'pass'}:$u{'change'}:$u{'min'}:". "$u{'max'}:$u{'warn'}:$u{'inactive'}:$u{'expire'}:\n"); } } }

Berikut adalah fungsi yang bertugas untuk menghapus user. Masih memanfaatkan daftar user passwd.

# delete_user(&details) sub delete_user { if (&passfiles_type() == 1) { &replace_file_line($config{'master_file'}, $_[0]->{'line'}); } else { &replace_file_line($config{'passwd_file'}, $_[0]->{'line'}); if (&passfiles_type() == 2) { &replace_file_line($config{'shadow_file'}, $_[0]->{'sline'}); } } }

Untuk melakukan administrasi pada group masih sama seperti diatas, informasi tentang group, pass, gid, members disimpan dalam array hashtable

bernama GROUP.

# list_groups() sub list_groups {

local(@rv, $lnum, $_, %idx, $g, $i, $j); $lnum = 0; open(GROUP, $config{'group_file'}); while(<GROUP>) { s/\r|\n//g; if (/\S/ && !/^[#\+\-]/) { @gr = split(/:/, $_, -1);

'gid' => $gr[2],'members' => $gr[3], 'line' => $lnum,'num' => scalar(@rv) }); $idx{$gr[0]} = $rv[$#rv];

} $lnum++; }

close(GROUP);

Untuk fungsi-fungsi yang lain seperti, menambah group baru, edit group, atau menghapus group pada prinsipnya sama seperti yang terjadi pada user. Perbedaannya hanya terdapat pada ulist dan glist nya saja.

c. Administrasi Printer

Dengan memanfaatkan PRINCAP (Printer Capability Database) dapat

dibuat fungsi-fungsi yang berguna untuk menambah, menghapus maupun edit printer. Princap berfungsi untuk menerjemahkan line printer. Berikut adalah program untuk mendapatkan printer sekaligus untuk mengetahui status printer tersebut.

#Sub_get_printer

# found the printer.. get info from printcap $prn{'name'} = $n[0]; if (@n > 2) { $prn{'alias'} = [ @n[1..$#n-1] ]; } if (@n > 1) { $prn{'desc'} = $n[$#n]; } $prn{'iface'} = $l->{'if'}; $prn{'banner'} = !defined($l->{'sh'}); $prn{'dev'} = $l->{'lp'}; $prn{'rhost'} = $l->{'rm'}; $prn{'rqueue'} = $l->{'rp'}; $prn{'msize'} = $l->{'mx#'}; # call lpc to get status

$out = `lpc status $prn{'name'} 2>&1`;

$prn{'accepting'} = ($out =~ /queuing is enabled/); $prn{'enabled'} = ($out =~ /printing is enabled/); # call lpq to get print jobs

while(<LPQ>) { chop;

if (/^Rank\s+Owner\s+/) { $doneheader++; }

elsif ($doneheader && /^(\S+)\s+(\S+)\s+(\d+)\s+(.*\S)\s+(\d+)\s+(\S+)$/) { local(%job); $job{'id'} = $3; $job{'user'} = $2; $job{'size'} = $5; $job{'file'} = $4; $job{'printing'} = ($1 eq "active"); push(@jobs, \%job);

Untuk menambah account printer baru dalam direktori /etc/printcap, panggil file handle CAP simpan dalam config{‘printcap_file’} cetak CAP dan jalankan subrutin make_printcap, maka data baru yang diinputkan oleh user akan disimpan dalam printcap_file. # create_printer(&details) sub create_printer { local(%cap); $cap{'sd'} = "$config{'spool_dir'}/$_[0]->{'name'}"; mkdir($cap{'sd'}, 0755); open(CAP, ">> $config{'printcap_file'}"); print CAP &make_printcap($_[0], \%cap),"\n"; close(CAP);

&apply_status($_[0]); }

Untuk merubah account yang sudah ada dapat mengambil daftar printer dalam list_printcab yang kemudian disimpan dalam sebuah array. Nama printer yang akan dihapus merupakan input dari user. Bila nama yang diinginkan tidak terdapat dalam daftar printer akan ditampilkan pesan kesalahan. Namun bila printer ditemukan akan ditampilkan.

# modify_printer(&details) sub modify_printer

{

local(@old, $o, $old, @cap); @old = &list_printcap(); foreach $o (@old) {

$o->{'name'} =~ /^([^\|]+)/; if ($1 eq $_[0]->{'name'}) {

# found current details $old = $o;

last; } }

if (!$old) { &error("Printer '$_[0]->{'name'}' no longer exists"); } open(CAP, $config{'printcap_file'});

@cap = <CAP>; close(CAP);

splice(@cap, $old->{'line'},

$old->{'eline'} - $old->{'line'} + 1, &make_printcap($_[0], $old)."\n");

Dokumen terkait