htpasswd.c revision 8c32cb0993834cf5345c2d23123340c280feaa31
* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * ==================================================================== * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * Portions of this software are based upon public domain software * originally written at the National Center for Supercomputing Applications, * University of Illinois, Urbana-Champaign. /****************************************************************************** ****************************************************************************** * NOTE! This program is not safe as a setuid executable! Do not make it ****************************************************************************** *****************************************************************************/ * htpasswd.c: simple program for manipulating password file for * Originally by Rob McCool * 2: Failure; command line syntax problem (usage message issued) * 3: Failure; password verification failure * 4: Failure; operation interrupted (such as with CTRL/C) * 5: Failure; buffer would overflow (username, filename, or computed * 6: Failure; username contains illegal or reserved characters #
endif /*CHARSET_EBCDIC*/ * This needs to be declared statically so the signal handler can * If our platform knows about the tmpnam() external buffer size, create * a buffer to pass in. This is needed in a threaded environment, or * one that thinks it is (like HP-UX). * Get a line of input from the user, not including any terminating if ((s[i] ==
0x4) || (s[i] ==
LF) || (i == (n -
1))) {
return (
feof(f) ?
1 : 0);
static void to64(
char *s,
unsigned long v,
int n)
static unsigned char itoa64[] =
/* 0 ... 63 => ASCII - 64 */ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
* Make a password record from the given information. A zero return * indicates success; failure means that the output buffer contains an /* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */ /* XXX this len limitation is not in sync with any HTTPd len. */ * Check to see if the buffer is large enough to hold the username, fprintf(
stderr,
"\thtpasswd -b[cmdps] passwordfile username password\n\n");
fprintf(
stderr,
" -n Don't update file; display results on stdout.\n");
fprintf(
stderr,
" -p Do not encrypt the password (plaintext).\n");
fprintf(
stderr,
" -b Use the password from the command line rather " "than prompting for it.\n");
"On Windows and TPF systems the '-m' flag is used by default.\n");
"On all other systems, the '-p' flag will probably not work.\n");
* Check to see if the specified file can be opened for the given * Return true if a file is readable. * Return true if the specified file can be opened for write access. * Return true if the named file exists, regardless of permissions. * Copy from the current position of one file to the current position * Let's do it. We end up doing a lot of file opening and closing, * but what do we care? This application isn't run constantly. #
endif /*CHARSET_EBCDIC*/ * Preliminary check to make sure they provided at least * three arguments, we'll do better argument checking as * we parse the command line. * Go through the argument list and pick out any options. They * have to precede any other arguments. for (i =
1; i <
argc; i++) {
* Make sure we still have exactly the right number of arguments left * (the filename, the username, and possibly the password if -b was fprintf(
stderr,
"%s: username contains illegal character '%c'\n",
"just not work on this platform.\n");
* Only do the file checks if we're supposed to frob it. * Verify that the file exists if -c was omitted. We give a special "%s: cannot modify file %s; use '-c' to create it\n",
* Verify that we can read the existing file in the case of an update * to it (rather than creation of a new one). * Now check to see if we can preserve an existing file in case * of password verification errors on a -c operation. "%s: existing auth data would be lost on " * Now verify that the file is writable! * All the file access checks (if any) have been made. Time to go to work; * try to create the record for the username in question. If that * fails, there's no need to waste any time on file manipulations. * Any error message text is returned in the record buffer, since * the mkrecord() routine doesn't have access to argv[]. * We can access the files the right way, and we have a record * to add or update. Let's do it.. * If we're not creating a new file, copy records from the existing * one to the temporary file until we find the specified user. if ((
line[0] ==
'#') || (
line[0] ==
'\0')) {
* See if this is our user. * Now add the user record we created. * If we're updating an existing file, there may be additional * records beyond the one we're updating, so copy them. * The temporary file now contains the information that should be * in the actual password file. Close the open files, re-open them * in the appropriate mode, and copy them file to the real one.