-.TH htpasswd 1 "February 1997"
+.TH htpasswd 1 "May 2000"
.\" The Apache Software License, Version 1.1
.\"
.\" Copyright (c) 2000 The Apache Software Foundation. All rights
]
[
.B \-m
+|
.B \-d
+|
.B \-p
+|
.B \-s
]
.I passwdfile
.I username
.I password
+.br
+.B htpasswd
+.B \-n
+[
+.B \-m
+|
+.B \-d
+|
+.B \-s
+|
+.B \-p
+]
+.I username
+.br
+.B htpasswd
+.B \-nb
+[
+.B \-m
+|
+.B \-d
+|
+.B \-s
+|
+.B \-p
+]
+.I username
+.I password
.SH DESCRIPTION
.B htpasswd
is used to create and update the flat-files used to store
Apache web server can be restricted to just the users listed
in the files created by
.B htpasswd.
-This program can only be used
-when the usernames are stored in a flat-file. To use a
+This program can only manage usernames and passwords
+stored in a flat-file. It can encrypt and display password information
+for use in other types of data stores, though. To use a
DBM database see
\fBdbmmanage\fP.
.PP
line.\fP
.IP \-c
Create the \fIpasswdfile\fP. If \fIpasswdfile\fP already exists, it
-is rewritten and truncated.
+is rewritten and truncated. This option cannot be combined with
+the \fB-n\fP option.
+.IP \-n
+Display the results on standard output rather than updating a file.
+This is useful for generating password records acceptable to Apache
+for inclusion in non-text data stores. This option changes the
+syntax of the command line, since the \fIpasswdfile\fP argument
+(usually the first one) is omitted. It cannot be combined with
+the \fB-c\fP option.
.IP \-m
Use MD5 encryption for passwords. On Windows and TPF, this is the default.
.IP \-d
Use crypt() encryption for passwords. The default on all platforms but
Windows and TPF. Though possibly supported by
.B htpasswd
-onm all platforms, it is not supported by the
+on all platforms, it is not supported by the
.B httpd
server on Windows and TPF.
.IP \-s
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\thtpasswd [-cmdps] passwordfile username\n");
fprintf(stderr, "\thtpasswd -b[cmdps] passwordfile username password\n\n");
+ fprintf(stderr, "\thtpasswd -n[mdps] username\n");
+ fprintf(stderr, "\thtpasswd -nb[mdps] username password\n");
fprintf(stderr, " -c Create a new file.\n");
+ fprintf(stderr, " -n Don't update file; display results on stdout.\n");
fprintf(stderr, " -m Force MD5 encryption of the password"
#if defined(WIN32) || defined(TPF)
" (default)"
int found = 0;
int alg = ALG_CRYPT;
int newfile = 0;
+ int nofile = 0;
int noninteractive = 0;
int i;
int args_left = 2;
if (*arg == 'c') {
newfile++;
}
+ else if (*arg == 'n') {
+ nofile++;
+ args_left--;
+ }
else if (*arg == 'm') {
alg = ALG_APMD5;
}
if ((argc - i) != args_left) {
return usage();
}
- if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) {
- fprintf(stderr, "%s: filename too long\n", argv[0]);
- return ERR_OVERFLOW;
+ if (newfile && nofile) {
+ fprintf(stderr, "%s: -c and -n options conflict\n", argv[0]);
+ return ERR_SYNTAX;
}
- strcpy(pwfilename, argv[i]);
- if (strlen(argv[i + 1]) > (sizeof(user) - 1)) {
- fprintf(stderr, "%s: username too long (>%d)\n", argv[0],
- sizeof(user) - 1);
- return ERR_OVERFLOW;
+ if (nofile) {
+ i--;
+ }
+ else {
+ if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) {
+ fprintf(stderr, "%s: filename too long\n", argv[0]);
+ return ERR_OVERFLOW;
+ }
+ strcpy(pwfilename, argv[i]);
+ if (strlen(argv[i + 1]) > (sizeof(user) - 1)) {
+ fprintf(stderr, "%s: username too long (>%d)\n", argv[0],
+ sizeof(user) - 1);
+ return ERR_OVERFLOW;
+ }
}
strcpy(user, argv[i + 1]);
if ((arg = strchr(user, ':')) != NULL) {
"just not work on this platform.\n");
}
#endif
- /*
- * Verify that the file exists if -c was omitted. We give a special
- * message if it doesn't.
- */
- if ((! newfile) && (! exists(pwfilename))) {
- fprintf(stderr, "%s: cannot modify file %s; use '-c' to create it\n",
- argv[0], pwfilename);
- perror("fopen");
- exit(ERR_FILEPERM);
- }
- /*
- * Verify that we can read the existing file in the case of an update
- * to it (rather than creation of a new one).
- */
- if ((! newfile) && (! readable(pwfilename))) {
- fprintf(stderr, "%s: cannot open file %s for read access\n",
- argv[0], pwfilename);
- perror("fopen");
- exit(ERR_FILEPERM);
- }
- /*
- * Now check to see if we can preserve an existing file in case
- * of password verification errors on a -c operation.
- */
- if (newfile && exists(pwfilename) && (! readable(pwfilename))) {
- fprintf(stderr, "%s: cannot open file %s for read access\n"
- "%s: existing auth data would be lost on password mismatch",
- argv[0], pwfilename, argv[0]);
- perror("fopen");
- exit(ERR_FILEPERM);
- }
- /*
- * Now verify that the file is writable!
- */
- if (! writable(pwfilename)) {
- fprintf(stderr, "%s: cannot open file %s for write access\n",
- argv[0], pwfilename);
- perror("fopen");
- exit(ERR_FILEPERM);
+ if (! nofile) {
+ /*
+ * 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
+ * message if it doesn't.
+ */
+ if ((! newfile) && (! exists(pwfilename))) {
+ fprintf(stderr,
+ "%s: cannot modify file %s; use '-c' to create it\n",
+ argv[0], pwfilename);
+ perror("fopen");
+ exit(ERR_FILEPERM);
+ }
+ /*
+ * Verify that we can read the existing file in the case of an update
+ * to it (rather than creation of a new one).
+ */
+ if ((! newfile) && (! readable(pwfilename))) {
+ fprintf(stderr, "%s: cannot open file %s for read access\n",
+ argv[0], pwfilename);
+ perror("fopen");
+ exit(ERR_FILEPERM);
+ }
+ /*
+ * Now check to see if we can preserve an existing file in case
+ * of password verification errors on a -c operation.
+ */
+ if (newfile && exists(pwfilename) && (! readable(pwfilename))) {
+ fprintf(stderr, "%s: cannot open file %s for read access\n"
+ "%s: existing auth data would be lost on "
+ "password mismatch",
+ argv[0], pwfilename, argv[0]);
+ perror("fopen");
+ exit(ERR_FILEPERM);
+ }
+ /*
+ * Now verify that the file is writable!
+ */
+ if (! writable(pwfilename)) {
+ fprintf(stderr, "%s: cannot open file %s for write access\n",
+ argv[0], pwfilename);
+ perror("fopen");
+ exit(ERR_FILEPERM);
+ }
}
/*
- * All the file access checks have been made. Time to go to work;
+ * 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
fprintf(stderr, "%s: %s\n", argv[0], record);
exit(i);
}
+ if (nofile) {
+ printf("%s\n", record);
+ exit(0);
+ }
/*
* We can access the files the right way, and we have a record