summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/issues/cgi_gateway.mdwn27
-rwxr-xr-xpinyadmin/sbin/newuser14
-rw-r--r--pinyweb/cgi-bin/piny-newuser.cgi27
3 files changed, 58 insertions, 10 deletions
diff --git a/docs/issues/cgi_gateway.mdwn b/docs/issues/cgi_gateway.mdwn
new file mode 100644
index 0000000..3fe9abc
--- /dev/null
+++ b/docs/issues/cgi_gateway.mdwn
@@ -0,0 +1,27 @@
+* Status: [[!taglink open]] <!-- Choose one: open, closed -->
+* Assigned to: [[!taglink jblake]] <!-- Choose one or more: jrayhawk, jblake -->
+* Priority: [[!taglink now]] <!-- Choose one: now, soon, later -->
+* Opened by: jrayhawk
+
+### Discussion
+
+In order for CGIs to work with the current paradigm, we'd need some mechanism
+for Apache to execute the various pinyadmin scripts as the involved user. We can
+either do this using sudo, which would require a lot of overhead in making and
+maintaining sudoers rules, or using an suid binary that does exactly what we
+need.
+
+Requirements:
+
+* executable only by www-data
+* takes as arguments
+ * username
+ * pinyadmin command
+ * pinyadmin command arguments
+* exits if username's uid < 1000
+* exits if username violates piny username constraints (specifically git- and
+ ikiwiki- are not allowed)
+* executes with the appropriate uid/gid the specified pinyadmin command and the
+ specified arguments
+
+Obviously any input on this concept is desirable.
diff --git a/pinyadmin/sbin/newuser b/pinyadmin/sbin/newuser
index c61cdec..f2dabc3 100755
--- a/pinyadmin/sbin/newuser
+++ b/pinyadmin/sbin/newuser
@@ -114,14 +114,12 @@ if ( scalar @ARGV == 3 and $ARGV[0] eq "--batch" ) {
};
# All the correctness checks should be repeated here. There are multiple
-# pathways to get to this point, but only a single path from here on down. We
-# don't need friendly error messages; whatever UI got us to this point *should*
-# have already caught these.
-exit 3 if ( not defined $email or $email eq "" );
-exit 3 if ( not defined $username eq "" );
-exit 3 if ( $username =~ /^(git|ikiwiki)-/ );
-exit 3 if ( $username !~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ );
-exit 3 if ( not defined $password or $password eq "" );
+# pathways to get to this point, but only a single path from here on down.
+if ( not defined $email or $email eq "" ) { print "Email address is undefined!\n"; exit 3; };
+if ( not defined $username or $username eq "" ) { print "Username is undefined!\n"; exit 3; };
+if ( $username =~ /^(git|ikiwiki)-/ ) { print "Username must not begin with git- or ikiwiki-!\n"; exit 3; };
+if ( $username !~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ ) { print "Usernames must consist only of letters, digits, underscores, periods, and dashes, and not start with a dash. Usernames are case sensitive.\n" };
+if ( not defined $password or $password eq "" ) { print "Password is undefined!\n"; exit 3; };
# Here on down is the actual creation code.
diff --git a/pinyweb/cgi-bin/piny-newuser.cgi b/pinyweb/cgi-bin/piny-newuser.cgi
index d10c6ba..ad46296 100644
--- a/pinyweb/cgi-bin/piny-newuser.cgi
+++ b/pinyweb/cgi-bin/piny-newuser.cgi
@@ -1,9 +1,32 @@
#!/usr/bin/perl
+$| = 1;
use warnings;
use CGI;
-print 'Content-type: text/plain
+use IPC::Open2;
-hello'
+$q = CGI->new;
+
+print( "Content-type: text/plain\n\n" );
+
+if( $q->param('n') && $q->param('a') && $q->param('p') ) {
+ # 03:57:44 omg/jrayhawk: system() lets me specify arguments as an array, and open() lets me work with stdout, but i would like something that does both
+ # 03:59:50 omg/jrayhawk: hahaha they recommend i open(, '-|') and then exec() in the child
+ # 03:59:55 omg/jrayhawk: fuck you, perl
+ $pid = open2( OUT, IN, '-' );
+ # make things flushier
+ select((select(IN), $| = 1)[0]);
+ select((select(OUT), $| = 1)[0]);
+ if( $pid ) {
+ print( IN $q->param('p') . "\n" );
+ while( <OUT> ) {
+ print;
+ };
+ } else {
+ exec( '/usr/bin/sudo', '/usr/sbin/newuser', '--batch', $q->param('a'), $q->param('n') ) || print 'could not execute newuser' && die;
+ };
+} else {
+ print 'Missing parameters.';
+};