Posted: April 20th, 2009 | Author: Troy | Filed under: Agile | Comments Off
Funny little story about an “abstract” (if you will), implementation of Scrum that I told to Ken Schwaber at his CSM class in Boston a few years back.
My wife and I, like a lot of parents of young children, were trying desperately one night to get our three year old daughter to eat all her dinner. We tried everything from cutting up her food into smaller and smaller bites to introducing various incentives like ice-cream and TV after dinner .. no matter what the tactic, we just couldn’t get her to eat and were met with all sorts of resistance. At one point, I even made myself more food so that I could eat it along with her. Nothing was working. It was starting to get later in the evening and we knew we couldn’t put her to bed without dinner and I needed to get prepared for the next day for our team’s morning Scrum.
I think maybe because this was on my mind, I decided as a last resort to try some very basic agile approaches to get our daughter to eat. Instead of telling her that she needed to eat her dinner or - insert various parenting text-book consequences here -, I decided to ask her “…how many bites would you like to have?”. Immediately, I had her attention and she responded without much hesitation … “zero”. Well, zero obviously wasn’t going to be acceptable so we negotiated a higher number and finally arrived at two I believe it was. Hey, two was better than zero and meant at least some progress. She agreed and actually began and finished her two bites and then looked to me for feedback on her recent accomplishment. I thought, “Great! Well, how many would you like to have now”. “Three”, she said, and so we proceeded along just like this until her whole plate was finished. My wife, couldn’t believe her eyes, nor anyone else that we demonstrated our strategy too. Scrum Master or Parent Coach? … I thought … hmmm.
Ken Schwaber made a great point to me after I told him this story. A very fundamental part of this success was the fact that my daughter actually felt she owned the task of eating her dinner which differentiated it from all the other day-to-day requests we make to our children. She really felt good about doing it.
Scrum works, even for three year olds.
Posted: July 22nd, 2009 | Author: Troy | Filed under: Linux, Solaris | No Comments »
The touch command is the easiest way to create new, empty files. It is also used to change the timestamps (i.e., dates and times of the most recent access and modification) on existing files and directories.
touch’s syntax is
touch [option] file_name(s)
When used without any options, touch creates new files for any file names that are provided as arguments (i.e., input data) if files with such names do not already exist. Touch can create any number of files simultaneously.
Thus, for example, the following command would create three new, empty files named file1, file2 and file3:
touch file1 file2 file3
A nice feature of touch is that, in contrast to some commands such as cp (which is used to copy files and directories) and mv (which is used to move or rename files and directories), it does not automatically overwrite (i.e., erase the contents of) existing files with the same name. Rather, it merely changes the last access times for such files to the current time.
Several of touch’s options are specifically designed to allow the user to change the timestamps for files. For example, the -a option changes only the access time, while the -m option changes only the modification time. The use of both of these options together changes both the access and modification times to the current time, for example:
touch -am file3
The -r (i.e., reference) option followed directly by a space and then by a file name tells touch to use that file’s time stamps instead of current time. For example, the following would tell it to use the times of file4 for file5:
touch -r file4 file5
The -B option modifies the timestamps by going back the specified number of seconds, and the -F option modifies the time by going forward the specified number of seconds. For example, the following command would make file7 30 seconds older than file6.
touch -r file6 -B 30 file7
The -d and -t options allow the user to add a specific last access time. The former is followed by a string (i.e., sequence of characters) in the date, month, year, minute:second format, and the latter uses a [[CC]YY]MMDDhhmm[.ss] format. For example, to change the last access time of file8 to 10:22 a.m. May 1, 2005, 1 May 2005 10:22 would be enclosed in single quotes and used as follows, i.e.,:
touch -d '1 May 2005 10:22' file8
Partial date-time strings can be used. For example, only the date need be provided, as shown for file9 below (in which case the time is automatically set to 0:00):
touch -d '14 May' file9
Just providing the time, as shown below, automatically changes the date to the current date:
touch -d '14:24' file9
The most commonly used way to view the last modification date for files is to use the ls command with its -l option. For example, in the case of a file named file10 this would be
ls -l file10
The complete timestamps for any file or directory can be viewed by using the stat command. For example, the following would show the timestamps for a file named file11:
stat file11
The –help option displays a basic list of options, and the –version option returns the version of the currently installed touch program.
Posted: July 15th, 2009 | Author: Troy | Filed under: Solaris | Tags: examples | No Comments »
Searching for Files (find)
The find command searches for files that meet conditions you specify, starting from a directory you name. For example, you might search for file names that match a certain pattern or that have been modified within a specified time frame.
Unlike most commands, find options are several characters long. You must specify the starting directory before your desired options.
In the previous example, directory is the name of the starting directory and options represents the options for the find command.
Each option describes a criterion for selecting a file. A file must meet all criteria to be selected. The more options you apply, the narrower the field becomes. The -print option indicates that you want the system to display the results.
The -name filename option tells find to select files that match filename. Here filename is taken to be the rightmost component of a file’s full path name. For example, the rightmost component of the file /usr/bin/calendar is calendar. This portion of a file’s name is often called the base name.
For example, to see which files within the current directory and its subdirectories end in s, type the following command.
$ find . -name '*s' -print
./programs
./programs/graphics
./programs/graphics/gks
./src/gks
$
|
The following table describes other options of the find command.
Table 3–1 find Options
| Option |
Description |
| -name filename |
Selects files with a rightmost component that matches filename. Surround filename with single quotes if it includes filename substitution patterns. |
| -user userid |
Selects files that are owned by userid. userid can be either a login name or user ID number. |
| -group group |
Selects files that belong to group. |
| -m -time n |
Selects files that have been modified within n days. |
| -newer checkfile |
Selects files that have been modified more recently than checkfile. |
You can specify an order of options by combining options within escaped parentheses (for example, \(options\) ). Within escaped parentheses, you can use the -o flag between options to indicate that find should select files that qualify under either category, rather than just those files that qualify under both categories.
$ find . \( -name AAA -o -name BBB \) -print
./AAA
./BBB
|
In the previous example, the find command searches in the . directory for all files that are named AAA, then looks for all files named BBB. find then displays the results of both searches.
You can invert the sense of an option by including an escaped exclamation point before the option. find then selects files for which the option does not apply:
$ find . \!-name BBB -print
./AAA
|
You can also use find to apply commands to the files it selects with the following options.
-exec command ‘{}’ \;
You terminate this option with an escaped semicolon (\;). The quoted braces are replaced with the file names that find selects.
You can use find to automatically remove temporary work files. If you name your temporary files consistently, you can use find to search for and remove these files. For example, if you name your temporary files junk or dummy, this command finds and removes the files.
$ find . \( -name junk -o -name dummy \) -exec rm '{}' \;
Posted: July 15th, 2009 | Author: Troy | Filed under: Linux | Tags: examples | No Comments »
The following examples illustrate typical uses of the command find for finding files on a computer.
find / -name game
Looks for a file named “game” starting at the root directory (searching all directories including mounted filesystems). The `-name’ option makes the search case sensitive. You can use the `-iname’ option to find something regardless of case.
find /home -user joe
Find every file under the directory /home owned by the user joe.
find /usr -name *stat
Find every file under the directory /usr ending in “stat”.
find /var/spool -mtime +60
Find every file under the directory /var/spool that was modified more than 60 days ago.
find /tmp -name core -type f -print | xargs /bin/rm -f
Find files named core in or below the directory /tmp and delete them. Note that this will work incorrectly if there are any filenames containing newlines, single or double quotes, or spaces.
find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
Find files named core in or below the directory /tmp and delete them, processing filenames in such a way that file or directory names containing single or double quotes, spaces or newlines are correctly handled. The -name test comes before the -type test in order to avoid having to call stat(2) on every file.
find . -type f -exec file ‘{}’ \;
Runs `file’ on every file in or below the current directory. Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though ‘;’ could have been used in that case also.
find / \( -perm -4000 -fprintf /root/suid.txt ‘%#m %u %p\n’ \), \
\( -size +100M -fprintf /root/big.txt ‘%-10s %p\n’ \)
Traverse the filesystem just once, listing setuid files and directories into /root/suid.txt and large files into /root/big.txt.
find $HOME -mtime 0
Search for files in your home directory which have been modified in the last twenty-four hours. This command works this way because the time since each file was last modified is divided by 24 hours and any remainder is discarded. That means that to match -mtime 0, a file will have to have a modification in the past which is less than 24 hours ago.
find . -perm 664
Search for files which have read and write permission for their owner, and group, but which other users can read but not write to. Files which meet these criteria but have other permissions bits set (for example if someone can execute the file) will not be matched.
find . -perm -664
Search for files which have read and write permission for their owner and group, and which other users can read, without regard to the presence of any extra permission bits (for example the executable bit). This will match a file which has mode 0777, for example.
find . -perm /222
Search for files which are writable by somebody (their owner, or their group, or anybody else).
find . -perm /220
find . -perm /u+w,g+w
find . -perm /u=w,g=w
All three of these commands do the same thing, but the first one uses the octal representation of the file mode, and the other two use the symbolic form. These commands all search for files which are writable by either their owner or their group. The files don’t have to be writable by both the owner and group to be matched; either will do.
find . -perm -220
find . -perm -g+w,u+w
Both these commands do the same thing; search for files which are writable by both their owner and their group.
find . -perm -444 -perm /222 ! -perm /111
find . -perm -a+r -perm /a+w ! -perm /a+x
These two commands both search for files that are readable for everybody (-perm -444 or -perm -a+r), have at least on write bit set (-perm /222 or -perm /a+w) but are not executable for anybody (! -perm /111 and ! -perm /a+x respectively)
Posted: June 5th, 2009 | Author: Troy | Filed under: Code, Misc | Tags: svn | No Comments »
svn switch --relocate http://old_svnserver/svn/repo/trunk http://new_svnserver/svn/repo/trunk .
Posted: May 28th, 2009 | Author: Troy | Filed under: Agile, Misc | No Comments »
I’ll extrapolate some of the ‘objective’ and ’subjective’ points for this discussion. I think it’s important to recognize and acknowledge these two categories of criteria in order to maintain and grow your organizations promises as they pertain to it’s offerings. Objectively - meeting deadlines, completing under budget, (completing at all or in some cases, stopping at the right time), low defect rates, customer financial ROI are all objective type criteria that “contribute” to the success story - if you will. Subjectively - the people factors such as raw emotions pertaining to satisfaction, confidence, delightment, excitement and happiness are equally if not more important than the objective criterias and also contribute to the success story. Scoring high in both these categories, which grows your success story, is critical.
The question beyond ‘my idea of what a successful project is characterized by’ then becomes - how do you measure and properly interpret ’success’ from what you know at the end of the project in terms of money spent, time taken etc. as well as what everyone involved thinks and feels about the project, how it went and what had been delivered? It’s important to be able to tell a good story at the very end.”
Posted: May 18th, 2009 | Author: Troy | Filed under: PHP | No Comments »
Works well with formatting output of form field keys.
preg_replace(’/(\w+)([A-Z])/U’, ‘\\1 \\2′, $string);
Posted: May 16th, 2009 | Author: Troy | Filed under: PHP | Tags: PHP | No Comments »
This one is very useful for randomizing html snippets such as image tags or just plain quotes.
/** Randomizes the order of the html in the $html array below.
* Don't forget the comma (,) at the end of each line (minus the last line) when adding more items!!
**/
$numItems = 2; // Change this value to add or decrease the number of elements in the $html array to be displayed.
$html = array (
'<img src="/images/imageOne.jpg" alt="" />' ,
'<img src="/images/imageTwo.jpg" alt="" />' ,
'<img src="/images/imageThree.jpg" alt="" />'
);
srand((float)microtime() * 1000000);
shuffle($html);
$i=0;
foreach ($html as $output)
{
if($i<$numItems)
echo $output;
$i++;
}
Posted: May 4th, 2009 | Author: Troy | Filed under: MySQL | Tags: MySQL | No Comments »
Will return if you have a record beginning with a distinct letter. sort them and count the records.
Useful for alphabetical lists.
For Left (First character):
SELECT DISTINCT LEFT(title. 1) AS letter. COUNT(*) as count FROM table GROUP BY letter ORDER BY count DESC;
For Left (Last character):
SELECT DISTINCT RIGHT(title. 1) AS letter. COUNT(*) as count FROM movies GROUP BY letter ORDER BY count DESC;
(Remember MySQL is optimized for count(*). count(*) actually being faster than count(id))
Posted: May 4th, 2009 | Author: Troy | Filed under: PHP | Tags: PHP | No Comments »
Great article about Form Post Hijacking I found at http://www.anders.com/projects/sysadmin/formPostHijacking/
AKA: Email Form Header Injection
The Problem.
Spammers are constantly being blacklisted and kicked off of networks. Because of this. tricking a non-spamming website into sending spam has become a high priority. One way for spammers to find vulnerable webservers is to test for CGI applications that would allow the spammer to enslave the webserver. Once a vulnerable webserver is found. the spammer can mask the true source of his spam while the enslaved webserver does the bulk of the work.
How do they do that?
A common task websites do is send an email to the owner of the website with whatever data someone has entered into a form. For example. one such script that does this is called formmail.pl or formmail.cgi from Mat’s Script Archive. In this script (as well as many others like it) some fields in the form are used directly in the header of an email. (for example. the Reply-To: field in the email is sometimes set to whatever the user of the form entered in the field called “email” so the owner of the website can easily hit “Reply” to that email and send a response.) If these fields are included unmodified. a spammer can simply overwrite the remaning header lines and effectivly submit any email they wish to through the underlying email system. effectivly enslaving the webserver / email system to send spam.
How exactly do they exploit the script?
The destination of an email is set in its headers. Headers. as everything else in an email. are just lines of text. What seperates the headers from the body of an email are just two blank lines. If your formmail script places anything in the header of an email that is unmodified from what the web user entered. they could easily add those two blank lines. This. of course. would just truncate the headers early and make the body of the email contain some of the headers as well. However. if the web user decides to throw in a few more headers before sending the two blank lines. the underlying email system will listen to those as well. So what the spammers are doing is including a “Bcc:” list of spam victims to the email. When the email subsystem gets the email. it blindly follows what is written in the headers and happily sends one copy of the message to each person listed in the “Bcc:” line. Now of course spammers will probably also add their own subject line and some spam content to the email.
In order to find vulnerable webservers to prey on. spammers usually test the form by sending a sample through that is Bcc’d to and email address they have access to. Usually this is some throw-away address such as a hijacked AOL address. Webmasters are usually alerted to this when they see 5 to 10 trial emails in usually less than one second. They Google the address and hopefully find a page like this one which explains what is going on.
So what can be done about it?
The simplest way to mitigate the danger is to disallow any linefeed or carriage return characters in fields used in email headers therefore disabeling an attacker’s ability to add those two blank lines and trick your mail system into sending whatever they want. Then the problem becomes one of cleaning up a little annoyance rather than being enslaved to do a spammer’s bidding.
Huh? How do I do that?
Well. this is where it becomes a little complicated. The answer to that question depends on what software the form processor on your webserver is using. If you didn’t write your own form processor. your first move is probably to go ask the people that helped you set up your website. Most common form mailers have had bug fixes released since this vulnerability first came out. Have your web hosting provider update their form post code.
If you know what you are doing. check all fields in forms that are used in email headers and strip out the carriage return (\r) and line feed (\n) characters. In perl. this is done like this:
$field =~ s/\r/ /g; $field =~ s/\n/ /g;
If you are using PHP. you can do this for each variable used in email headers:
$_POST['email'] = preg_replace(”/\r/”. “”. $_POST['email']); $_POST['email'] = preg_replace(”/\n/”. “”. $_POST['email']);
How do I know if I’ve been hacked?
As most form to email scripts don’t write down what they are doing in a file somewhere. the best way to tell if your setup has been enslaved to send spam is to check your mailserver logs. If you are with a web hosting provider. they can usually check the logs for you.
What should I do if I’ve been hacked?
You should update your form mailer scripts so continuing attempts are not successful. (do this as described above) The you might want to chase down the throw-away spammer email address used to test for the vulnerability. Most I have seen to date have been addresses at AOL. so you should complain to abuse at aol.com or. as this is a Terms of Service violation. to tosgeneral at aol.com. Many people have already done so with limited effect. so don’t expect AOL to come swooping in and fix everything. but its at least covering the bases.
OK. so I’m clean. Now how do I stop the annoying test emails?
Again. go ask your hosting provider. However. if you have to make the edits on your own. find some fingerprint in the email that flags it as obviously bad. Like if the email field contains the characters “Bcc:”. chances are you are looking at a probe for vulnerability. Just put an “if” statement around the block of code that sends you an email that tests for that. Don’t forget to ignore case so “Bcc:” and “bcc:” are caught. Alternativly you could just look for the two blank lines. however you should be carefull about “\r\n\r\n” and “\n\n” which both will be interpreted as two blank lines. If you are going to do it this way. I suggest you kill all “\r” characters and then search for “\n\n”.
What else can be done?
A better (though more complicated) way to get around all of this is to require something that is easy for a human but hard for a computer to do. One such method that is quite popular is to use a Captcha image with some text in it that the user must enter before submitting the form. Personally. I don’t like the terrible user experience captcha imposes so I favor an image based recognition requirement to submit the form such as the one at the top-right on this page. As you reload the page. notice the images change. The downside with this method is that it takes some substantial server-side programming. which again is heavily dependant on your particular setup. However if you head over to JustHumans.com. you can find a hosted version of this system. Just sign up for an account and generate some JavaScript code to replace your submit button.
If you have other comments. post them on my blog post covering form spam. Link to this page if you think it has been helpfull so others can find it.
Posted: May 4th, 2009 | Author: Troy | Filed under: Joomla! | Tags: Joomla! | No Comments »
The requirement for client site was to have two user groups that are not natively part of the Joomla core access designated group protected content items. Here’s how I did it.
First the SQL to change the database to add the new user groups:
[mysql]
SET @parent_name = ‘Public Frontend’;
SET @new_name = ‘Agents’;
– Select the parent node to insert after
SELECT @ins_id := group_id. @ins_lft := lft. @ins_rgt := rgt
FROM jos_core_acl_aro_groups
WHERE name = @parent_name;
SELECT @new_id := MAX(group_id) + 1 FROM jos_core_acl_aro_groups;
– Make room for the new node
UPDATE jos_core_acl_aro_groups SET rgt=rgt+2 WHERE rgt>=@ins_rgt;
UPDATE jos_core_acl_aro_groups SET lft=lft+2 WHERE lft>@ins_rgt;
– Insert the new node
INSERT INTO jos_core_acl_aro_groups (group_id.parent_id.name.lft.rgt)
VALUES (@new_id.@ins_id.@new_name.@ins_rgt.@ins_rgt+1);
[/mysql]
THE FILES:
/includes/joomla.php
Wrote a new function to check the users actual group id:
/*********************** CHECK USERs GROUP ID - TD Mar 30 /07 ************/
function getUsersGroupId()
{
global $database. $my;
$accessQuery = "SELECT a.id ".
"FROM jos_groups a. jos_users b. jos_core_acl_aro_groups c ".
"WHERE c.group_id = b.gid ".
"AND c.name = a.name ".
"AND b.id = ".$my->id;
$database->setQuery($accessQuery);
$database->query();
$accessRes = $database->loadResult();
return $accessRes;
}
/********************* END CHECK USERs GROUP ID *************************/
Then I changed up the mosMenuCheck function slightly to use the above function to get the users actual group id and return that instead of the gid when logged in. Here’s what I did just below the globals declaration:
/******* Get users group id for content item permission checking **********/
$ugid = "";
$ugid = getUsersGroupId();
/**************************************************************************/
and then instead of “return ($access <= $gid)” I did this:
// Return the users group id or the gid depending if logged in or not - TD - Mar 30 / 07
if($ugid > 0)
return $ugid;
else
return ($access <= $gid);
/modules/mod_mainmenu.php
I have a bit of a customized menu class here originally from the JPL project so basically what I did here was to get the class to check access based on the users actual group id if they or logged in or the gid when they are not. Basically the SQL that pulls together the menu links should be checking access (AND access <= “.(int)$my->gid;). I simply added the condition where if I can get the users actual group id from a function similar to getUsersGroupId() then use the value that the function returns in the AND access clause in the SQL. Here’s exactly what that looks like:
$accessRes being what the function returns. In this case in the menu class. I simply wrote the function code not as a function but within the code.
if(!$accessRes)
$secondLvlQry .= "\n AND access <= " . (int) $my->gid;
else
$secondLvlQry .= "\n AND access IN (0.".$accessRes.")";
/components/com_content/content.php
In the showItem function I did the following right below the globals declarations:
// *******************Added to check users group id - TD Mar 30 / 07 **************
global $my;
if($my->id)
{
$accessRes = "";
$accessRes = getUsersGroupId();
}
//*********************************************************************************//
Then I changed up the main SQL query just slightly in the AND clause that checks access:
// If result from access query above then - TD //
if(!$accessRes)
$query .= "\n AND a.access <= " . (int) $gid;
else
$query .= "\n AND a.access IN (0.".$accessRes.")";
In the show function. I commented out the following:
/*
if ( $row->access > $gid )
{
if ( $noauth )
{
mosNotAuth();
return;
}
else
{
if ( !( $params->get( 'intro_only' ) ) )
{
mosNotAuth();
return;
}
}
}*/