#Checks if $username begins by a letter and contains only letters, digits, -, _ or .
proc tc2:username_isvalid {username}{
regexp{^[A-Za-z][A-Za-z0-9_\-\.]*$}$username
}
#Determines if $username exists on the system
#SECURITY: to avoid shell injection, call first tc2:username_isvalid $username
proc tc2:username_exists {username}{
#TODO: Windows and other OSes (this line has been tested under FreeBSD)
if{[exec-- logins -oxl $username]==""}{
return0
}{
return1
}
}
#Gets server hostname
proc tc2:hostname {}{
exec hostname -s
}
#Determines if $username is root
proc tc2:isroot {username}{
#Validates input data
set username [string tolower $username]
if![tc2:username_isvalid $username]{
return0
}
#Check 1 - User has local accreditation
if![sql"SELECT count(*) FROM tc2_roots WHERE account_username = '$username' AND server_name = '[sqlescape [tc2:hostname]]'"]{
return0
}
#Check 2 - User is in the group wheel on the server
if{[lsearch[exec-- id -Gn $username] wheel]=="-1"}{
return0
}{
return1
}
}
#Determines if $requester is *EXPLICITELY* allowed to allowed to manage the account $user
#When you invoke this proc, you should also check if the user is root.
# e.g. if {[tc2:isroot $requester] || [tc2:userallow $requester $user]} { ... }
proc tc2:userallow {requester user}{
set sql "SELECT count(*) FROM tc2_users_permissions WHERE server_name = '[sqlescape [tc2:hostname]]' AND account_username = '[sqlescape $user]' AND user_id = [getuserid $user]"
putdebug$sql
sql$sql
}
#tc2:getpermissions on $username: Gets permissions on the $username account
#tc2:getpermissions from $username: Gets permissions $username have on server accounts
proc tc2:getpermissions {keyword username}{
switch$keyword{
"from"{
set sql "SELECT account_username FROM tc2_users_permissions WHERE server_name = '[sqlescape [tc2:hostname]]' AND user_id = '[getuserid $username]'"
}
"on"{
set sql "SELECT u.username FROM tc2_users_permissions p, users u WHERE p.server_name = '[sqlescape [tc2:hostname]]' AND p.account_username = '$username' AND u.user_id = p.user_id"
}
default{
error"from or on expected"
}
}
set accounts ""
foreach row [sql$sql]{
lappend accounts [lindex$row0]
}
}
#Creates an account $username from the $specified group
proc tc2:createaccount {username group}{
if{$group=="web"}{
set key "tc2.[tc2:hostname].wwwroot"
if{[set wwwroot [registry get $key]]==""}{
error"You must define the registry key $key"
}
set homedir $wwwroot/$username
if[catch{
set reply [exec-- pw user add $username-g $group-b $wwwroot-w random]
exec-- mkdir -p -m 0711$homedir
exec-- chown -R $username:web$homedir
} err]{
append reply " / "
append reply $err
}
return$reply
}{
exec-- pw user add $username-g $group-m -w random
}
}
#Checks if $username begins by a letter and contains only letters, digits, -, _ or .
return"0 {$mandataire doesn't have a bot account, and so, no such permission.}"
}
#Checks if the permission exists
if![tc2:userallow $requester$mandataire]{
return"0 {$mandataire haven't had an access to $username account.}"
}
#Removess the permission
sql"DELETE FROM tc2_users_permissions WHERE server_name = '[sqlescape [tc2:hostname]]' AND account_username = '$username' AND user_id = '$mandataire_user_id'"
return"1 {$mandataire doesn't have access to $username account anymore.}"
}
"+root"{
#Checks right and need
if![tc2:isroot $requester]{
return"0 {you don't have root authority yourself.}"
}
if[tc2:isroot $username]{
return"0 {$username have already root authority.}"
return"0 {you don't have the authority to create a website linked to $user account.}"
}
#Creates needed directories
if![file exists $wwwdir]{
exec-- mkdir -m 0711-p $wwwdir
exec-- chown $user$wwwdir
}
if![file exists $logdir]{
exec-- mkdir -m 0711-p $wwwdir
exec-- chown $user$wwwdir
}
#Prepares new config block
set fd [open$tpldir/$tpl r]
set template [read$fd]
close$fd
set xtra ""
foreach option "ssl php upstream"{
if$$option{
set xtrafile $tpldir/extra-$option.tpl
if![file exists $xtrafile]{
return[list0"Template file not found: $xtrafile"]
}
set fd [open$xtrafile]
append xtra "\n\n"
append xtra [read$fd]
close$fd
}
}
set configblock [string map [list%EXTRACONFIG%$xtra]$template]
set configblock [string map [list%REQUESTER%$requester%TIME%[unixtime]%COMMENT%"Autogenerated by $username"%FULLDOMAIN%$fulldomain%LOGDIR%$logdir%SSLDIR%$ssldir%SUBDOMAIN%$subdomain%WWWDIR%$wwwdir%PHPFPMPORT%$phpfpmport%CUSTOM-PREPHP%""%CUSTOM-PHP%""%CUSTOM%""%UPSTREAMKEYWORD%$upstream_keyword%UPSTREAMURL%$upstream_url%INDEX%$index%EXTRACONFIG%$xtra]$configblock]
#Opens or creates domain config file
if[file exists $config]{
set fd [open$config a]
}{
#We use a also template for ou config file header
set fd [open$tpldir/vhost-header.tpl r]
set template [read$fd]
close$fd
set fd [open$config w]
puts$fd[string map "%DOMAIN% $domain"$template]
flush$fd
}
#Writes new config block
puts$fd""
puts$fd$configblock
close$fd
return[list1"done, $fulldomain server block added to $config ; use .nginx reload to save"]
}
edit{
return[list1"not yet implemented, edit the file $config"]
}
}
}
return{0"usage: .nginx server add/edit domain \[options\]"}
}
""{
return{0"server add, server edit, status or reload expected"}