diff options
-rw-r--r-- | docs/issues/cgi_gateway.mdwn | 27 | ||||
-rwxr-xr-x | pinyadmin/sbin/newuser | 14 | ||||
-rw-r--r-- | pinyweb/cgi-bin/piny-newuser.cgi | 27 |
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.'; +}; |