summaryrefslogtreecommitdiffstats
path: root/pw
diff options
context:
space:
mode:
authorDavid Nugent <davidn@FreeBSD.org>1996-12-21 15:35:45 +0000
committerDavid Nugent <davidn@FreeBSD.org>1996-12-21 15:35:45 +0000
commit0c9f365da25caa3b04bcfe82b70ee49aab96e619 (patch)
tree3307dfadeecd6d5dccb408b4e3ae778dfc80b56f /pw
parent16a21e7a7bdcc33504a9ee08c9af57d1c8dc874f (diff)
downloadpw-darwin-0c9f365da25caa3b04bcfe82b70ee49aab96e619.tar.gz
pw-darwin-0c9f365da25caa3b04bcfe82b70ee49aab96e619.tar.zst
pw-darwin-0c9f365da25caa3b04bcfe82b70ee49aab96e619.zip
1) 200 users per group limitation removed and pw
will handle lines of any length in /etc/group. 2) Fixed bug with usermod -d not updating user's home directory. 3) Minor formatting display changes/fixes with *show -P.
Diffstat (limited to 'pw')
-rw-r--r--pw/edgroup.c234
-rw-r--r--pw/fileupd.c61
-rw-r--r--pw/grupd.c66
-rw-r--r--pw/pw.h5
-rw-r--r--pw/pw_conf.c256
-rw-r--r--pw/pw_group.c45
-rw-r--r--pw/pw_user.c79
-rw-r--r--pw/pwupd.c4
-rw-r--r--pw/pwupd.h12
9 files changed, 472 insertions, 290 deletions
diff --git a/pw/edgroup.c b/pw/edgroup.c
index 34a22d1..c7b379c 100644
--- a/pw/edgroup.c
+++ b/pw/edgroup.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: edgroup.c,v 1.1.1.1 1996/12/09 14:05:35 joerg Exp $
+ * $Id: edgroup.c,v 1.1.1.2 1996/12/10 23:58:54 joerg Exp $
*/
#include <stdio.h>
@@ -47,7 +47,7 @@ isingroup(char const * name, char **mem)
{
int i;
- for (i = 0; i < MAXGROUPS && mem[i] != NULL; i++)
+ for (i = 0; mem[i] != NULL; i++)
if (strcmp(name, mem[i]) == 0)
return i;
return -1;
@@ -76,119 +76,143 @@ editgroups(char *name, char **groups)
if ((outfp = fdopen(outfd, "w+")) == NULL)
close(outfd);
else {
- char line[MAXPWLINE];
- char outl[MAXPWLINE];
-
- while (fgets(line, sizeof(line), infp) != NULL) {
- char *p = strchr(line, '\n');
-
- if (p == NULL) { /* Line too long */
- int ch;
-
- fputs(line, outfp);
- while ((ch = fgetc(infp)) != EOF) {
- fputc(ch, outfp);
- if (ch == '\n')
- break;
- }
- continue;
- }
- if (*line == '#')
- strcpy(outl, line);
- else if (*line == '\n')
- *outl = '\0';
- else {
- int i,
- mno = 0;
- char *cp = line;
- char const *sep = ":\n";
- struct group grp;
- char *mems[MAXGROUPS];
-
- memset(&grp, 0, sizeof grp);
- grp.gr_mem = mems;
- for (i = 0; (p = strsep(&cp, sep)) != NULL; i++) {
- switch (i) {
- case 0: /* Group name */
- grp.gr_name = p;
- break;
- case 1: /* Group password */
- grp.gr_passwd = p;
- break;
- case 2: /* Group id */
- grp.gr_gid = atoi(p);
- break;
- case 3: /* Member list */
- cp = p;
- sep = ",\n";
- break;
- default: /* Individual members */
- if (mno < MAXGROUPS && *p)
- mems[mno++] = p;
- break;
+ int linelen = PWBUFSZ;
+ int outlen = PWBUFSZ;
+ int memlen = 200; /* Arbitrary */
+ char *line = malloc(linelen);
+ char *outl = malloc(outlen);
+ char **mems = malloc(memlen * sizeof(char *));
+ int namlen = strlen(name);
+
+ if (line == NULL || outl == NULL || mems == NULL) {
+ mem_abort:
+ rc = 0;
+ } else {
+ while (fgets(line, linelen, infp) != NULL) {
+ char *p;
+ int l;
+
+ while ((p = strchr(line, '\n')) == NULL)
+ {
+ if (extendline(&line, &linelen, linelen + PWBUFSZ) == -1) {
+ goto mem_abort;
}
+ l = strlen(line);
+ if (fgets(line + l, linelen - l, infp) == NULL)
+ break; /* No newline terminator on last line */
}
- if (i < 2) /* Bail out -
- * insufficient fields */
- continue;
-
- for (i = mno; i < MAXGROUPS; i++)
- mems[i] = NULL;
-
- /*
- * Delete from group, or add to group?
- */
- if (groups == NULL || isingroup(grp.gr_name, groups) == -1) { /* Delete */
- int idx;
+ l = strlen(line) + namlen + 1;
+ if (extendline(&outl, &outlen, l) == -1) {
+ goto mem_abort;
+ }
+ if (*line == '#')
+ strcpy(outl, line);
+ else if (*line == '\n')
+ *outl = '\0';
+ else {
+ int i,
+ mno = 0;
+ char *cp = line;
+ char const *sep = ":\n";
+ struct group grp;
+
+ memset(&grp, 0, sizeof grp);
+ for (i = 0; (p = strsep(&cp, sep)) != NULL; i++) {
+ switch (i) {
+ case 0: /* Group name */
+ grp.gr_name = p;
+ break;
+ case 1: /* Group password */
+ grp.gr_passwd = p;
+ break;
+ case 2: /* Group id */
+ grp.gr_gid = atoi(p);
+ break;
+ case 3: /* Member list */
+ cp = p;
+ sep = ",\n";
+ break;
+ default: /* Individual members */
+ if (*p) {
+ if (extendarray(&mems, &memlen, mno + 2) == -1) {
+ goto mem_abort;
+ }
+ mems[mno++] = p;
+ }
+ break;
+ }
+ }
+ if (i < 2) /* Bail out - insufficient fields */
+ continue;
- while ((idx = isingroup(name, mems)) != -1) {
- for (i = idx; i < (MAXGROUPS - 1); i++)
- mems[i] = mems[i + 1];
+ grp.gr_mem = mems;
+ for (i = mno; i < memlen; i++)
mems[i] = NULL;
- --mno;
- }
/*
- * Special case - deleting user and group may be user's own
+ * Delete from group, or add to group?
*/
- if (groups == NULL && mems[0] == NULL && strcmp(name, grp.gr_name) == 0) { /* First, make _sure_ we
- * don't have other
- * members */
- struct passwd *pwd;
-
- setpwent();
- while ((pwd = getpwent()) != NULL && pwd->pw_gid != grp.gr_gid);
- endpwent();
- if (pwd == NULL) /* No members at all */
- continue; /* Drop the group */
+ if (groups == NULL || isingroup(grp.gr_name, groups) == -1) { /* Delete */
+ int idx;
+
+ while ((idx = isingroup(name, mems)) != -1) {
+ for (i = idx; i < (memlen - 1); i++)
+ mems[i] = mems[i + 1];
+ mems[i] = NULL;
+ --mno;
+ }
+ /*
+ * Special case - deleting user and group may be user's own
+ */
+ if (groups == NULL && mems[0] == NULL && strcmp(name, grp.gr_name) == 0) {
+ /*
+ * First, make _sure_ we don't have other members
+ */
+ struct passwd *pwd;
+
+ setpwent();
+ while ((pwd = getpwent()) != NULL && pwd->pw_gid != grp.gr_gid);
+ endpwent();
+ if (pwd == NULL) /* No members at all */
+ continue; /* Drop the group */
+ }
+ } else if (isingroup(name, mems) == -1) {
+ if (extendarray(&mems, &memlen, mno + 2) == -1) {
+ goto mem_abort;
+ }
+ grp.gr_mem = mems; /* May have realloced() */
+ mems[mno++] = name;
+ mems[mno ] = NULL;
}
- } else if (isingroup(name, mems) == -1)
- mems[mno++] = name;
- fmtgrentry(outl, &grp, PWF_GROUP);
+ fmtgrentry(&outl, &outlen, &grp, PWF_GROUP);
+ }
+ fputs(outl, outfp);
+ }
+ if (fflush(outfp) != EOF) {
+ rc = 1;
+
+ /*
+ * Copy data back into the original file and truncate
+ */
+ rewind(infp);
+ rewind(outfp);
+ while (fgets(outl, outlen, outfp) != NULL)
+ fputs(outl, infp);
+
+ /*
+ * This is a gross hack, but we may have corrupted the
+ * original file. Unfortunately, it will lose preservation
+ * of the inode.
+ */
+ if (fflush(infp) == EOF || ferror(infp))
+ rc = rename(grouptmp, groupfile) == 0;
+ else
+ ftruncate(infd, ftell(infp));
}
- fputs(outl, outfp);
- }
- if (fflush(outfp) != EOF) {
- rc = 1;
-
- /*
- * Copy data back into the original file and truncate
- */
- rewind(infp);
- rewind(outfp);
- while (fgets(line, sizeof(line), outfp) != NULL)
- fputs(line, infp);
-
- /*
- * This is a gross hack, but we may have corrupted the
- * original file. Unfortunately, it will lose preservation
- * of the inode.
- */
- if (fflush(infp) == EOF || ferror(infp))
- rc = rename(grouptmp, groupfile) == 0;
- else
- ftruncate(infd, ftell(infp));
}
+ free(mems);
+ free(outl);
+ free(line);
fclose(outfp);
}
remove(grouptmp);
diff --git a/pw/fileupd.c b/pw/fileupd.c
index 0abaac6..e49e407 100644
--- a/pw/fileupd.c
+++ b/pw/fileupd.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: fileupd.c,v 1.1.1.1 1996/12/09 14:05:35 joerg Exp $
+ * $Id: fileupd.c,v 1.1.1.2 1996/12/10 23:58:55 joerg Exp $
*/
#include <stdio.h>
@@ -39,6 +39,33 @@
#include "pwupd.h"
int
+extendline(char **buf, int * buflen, int needed)
+{
+ if (needed > *buflen) {
+ char *tmp = realloc(*buf, needed);
+ if (tmp == NULL)
+ return -1;
+ *buf = tmp;
+ *buflen = needed;
+ }
+ return *buflen;
+}
+
+int
+extendarray(char ***buf, int * buflen, int needed)
+{
+ if (needed > *buflen) {
+ char **tmp = realloc(*buf, needed * sizeof(char *));
+ if (tmp == NULL)
+ return -1;
+ *buf = tmp;
+ *buflen = needed;
+ }
+ return *buflen;
+}
+
+
+int
fileupdate(char const * filename, mode_t fmode, char const * newline, char const * prefix, int pfxlen, int updmode)
{
int rc = 0;
@@ -67,21 +94,28 @@ fileupdate(char const * filename, mode_t fmode, char const * newline, char const
close(outfd);
else {
int updated = UPD_CREATE;
- char line[2048];
+ int linesize = PWBUFSZ;
+ char *line = malloc(linesize);
- while (fgets(line, sizeof(line), infp) != NULL) {
+ nextline:
+ while (fgets(line, linesize, infp) != NULL) {
char *p = strchr(line, '\n');
- if (p == NULL) { /* Line too long */
- int ch;
-
- fputs(line, outfp);
- while ((ch = fgetc(infp)) != EOF) {
- fputc(ch, outfp);
- if (ch == '\n')
- break;
+ while ((p = strchr(line, '\n')) == NULL) {
+ int l;
+ if (extendline(&line, &linesize, linesize + PWBUFSZ) == -1) {
+ int ch;
+ fputs(line, outfp);
+ while ((ch = fgetc(infp)) != EOF) {
+ fputc(ch, outfp);
+ if (ch == '\n')
+ break;
+ }
+ goto nextline;
}
- continue;
+ l = strlen(line);
+ if (fgets(line + l, linesize - l, infp) == NULL)
+ break;
}
if (*line != '#' && *line != '\n') {
if (!updated && strncmp(line, prefix, pfxlen) == 0) {
@@ -127,7 +161,7 @@ fileupdate(char const * filename, mode_t fmode, char const * newline, char const
*/
rewind(infp);
rewind(outfp);
- while (fgets(line, sizeof(line), outfp) != NULL)
+ while (fgets(line, linesize, outfp) != NULL)
fputs(line, infp);
/*
@@ -141,6 +175,7 @@ fileupdate(char const * filename, mode_t fmode, char const * newline, char const
ftruncate(infd, ftell(infp));
}
}
+ free(line);
fclose(outfp);
}
remove(file);
diff --git a/pw/grupd.c b/pw/grupd.c
index 784dbe5..725cf09 100644
--- a/pw/grupd.c
+++ b/pw/grupd.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: grupd.c,v 1.1.1.1 1996/12/09 14:05:35 joerg Exp $
+ * $Id: grupd.c,v 1.1.1.2 1996/12/10 23:58:56 joerg Exp $
*/
#include <stdio.h>
@@ -38,30 +38,51 @@
#include "pwupd.h"
int
-fmtgrentry(char *buf, struct group * grp, int type)
+fmtgrentry(char **buf, int * buflen, struct group * grp, int type)
{
int i, l;
- if (type == PWF_STANDARD)
- l = sprintf(buf, "%s:*:%ld:", grp->gr_name, (long) grp->gr_gid);
- else
- l = sprintf(buf, "%s:%s:%ld:", grp->gr_name, grp->gr_passwd, (long) grp->gr_gid);
-
/*
- * Now, list members
+ * Since a group line is of arbitrary length,
+ * we need to calculate up-front just how long
+ * it will need to be...
*/
- for (i = 0; i < 200 && grp->gr_mem[i]; i++)
- l += sprintf(buf + l, "%s%s", i ? "," : "", grp->gr_mem[i]);
- buf[l++] = '\n';
- buf[l] = '\0';
+ /* groupname : password : gid : */
+ l = strlen(grp->gr_name) + 1 + strlen(grp->gr_passwd) + 1 + 5 + 1;
+ /* group members + comma separator */
+ for (i = 0; grp->gr_mem[i] != NULL; i++) {
+ l += strlen(grp->gr_mem[i]) + 1;
+ }
+ l += 2; /* For newline & NUL */
+ if (extendline(buf, buflen, l) == -1)
+ l = -1;
+ else{
+ /*
+ * Now we can safely format
+ */
+ if (type == PWF_STANDARD)
+ l = sprintf(*buf, "%s:*:%ld:", grp->gr_name, (long) grp->gr_gid);
+ else
+ l = sprintf(*buf, "%s:%s:%ld:", grp->gr_name, grp->gr_passwd, (long) grp->gr_gid);
+
+ /*
+ * List members
+ */
+ for (i = 0; grp->gr_mem[i] != NULL; i++) {
+ l += sprintf(*buf + l, "%s%s", i ? "," : "", grp->gr_mem[i]);
+ }
+
+ (*buf)[l++] = '\n';
+ (*buf)[l] = '\0';
+ }
return l;
}
int
-fmtgrent(char *buf, struct group * grp)
+fmtgrent(char **buf, int * buflen, struct group * grp)
{
- return fmtgrentry(buf, grp, PWF_STANDARD);
+ return fmtgrentry(buf, buflen, grp, PWF_STANDARD);
}
@@ -69,20 +90,23 @@ static int
gr_update(struct group * grp, char const * group, int mode)
{
int l;
- char pfx[32];
- char grbuf[MAXPWLINE];
+ char pfx[64];
+ int grbuflen = 0;
+ char *grbuf = NULL;
endgrent();
- l = sprintf(pfx, "%s:", group);
+ l = snprintf(pfx, sizeof pfx, "%s:", group);
/*
* Update the group file
*/
- if (grp == NULL)
- *grbuf = '\0';
+ if (grp != NULL && fmtgrentry(&grbuf, &grbuflen, grp, PWF_PASSWD) == -1)
+ l = -1;
else
- fmtgrentry(grbuf, grp, PWF_PASSWD);
- return fileupdate(_PATH_GROUP, 0644, grbuf, pfx, l, mode);
+ l = fileupdate(_PATH_GROUP, 0644, grbuf, pfx, l, mode);
+ if (grbuf != NULL)
+ free(grbuf);
+ return l;
}
diff --git a/pw/pw.h b/pw/pw.h
index 57c9bce..7c8cff5 100644
--- a/pw/pw.h
+++ b/pw/pw.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pw.h,v 1.1.1.3 1996/12/10 23:58:59 joerg Exp $
+ * $Id: pw.h,v 1.2 1996/12/19 15:22:42 davidn Exp $
*/
#include <stdio.h>
@@ -86,12 +86,12 @@ struct userconf
gid_t min_gid, max_gid; /* Allowed range of gids */
int expire_days; /* Days to expiry */
int password_days; /* Days to password expiry */
+ int numgroups; /* (internal) size of default_group array */
};
#define _PATH_PW_CONF "/etc/pw.conf"
#define _UC_MAXLINE 1024
#define _UC_MAXSHELLS 32
-#define _UC_MAXGROUPS 200
struct userconf *read_userconfig(char const * file);
int write_userconfig(char const * file);
@@ -111,7 +111,6 @@ int fmtpwent(char *buf, struct passwd * pwd);
int addgrent(struct group * grp);
int delgrent(struct group * grp);
int chggrent(char const * login, struct group * grp);
-int fmtgrent(char *buf, struct group * grp);
int boolean_val(char const * str, int dflt);
char const *boolean_str(int val);
diff --git a/pw/pw_conf.c b/pw/pw_conf.c
index 77778f3..8a0e644 100644
--- a/pw/pw_conf.c
+++ b/pw/pw_conf.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pw_conf.c,v 1.1.1.1 1996/12/09 14:05:35 joerg Exp $
+ * $Id: pw_conf.c,v 1.1.1.2 1996/12/10 23:59:00 joerg Exp $
*/
#include <string.h>
@@ -31,6 +31,7 @@
#include <fcntl.h>
#include "pw.h"
+#include "pwupd.h"
#define debugging 0
@@ -66,11 +67,6 @@ static char *system_shells[_UC_MAXSHELLS] =
"csh"
};
-static char *default_groups[_UC_MAXGROUPS] =
-{
- NULL
-};
-
static char const *booltrue[] =
{
"yes", "true", "1", "on", NULL
@@ -93,7 +89,7 @@ static struct userconf config =
system_shells, /* List of shells (first is default) */
bourne_shell, /* Default shell */
NULL, /* Default group name */
- default_groups, /* Default (additional) groups */
+ NULL, /* Default (additional) groups */
NULL, /* Default login class */
1000, 32000, /* Allowed range of uids */
1000, 32000, /* Allowed range of gids */
@@ -212,126 +208,143 @@ newstr(char const * p)
return q;
}
+#define LNBUFSZ 1024
+
struct userconf *
read_userconfig(char const * file)
{
FILE *fp;
+ extendarray(&config.groups, &config.numgroups, 200);
+ memset(config.groups, 0, config.numgroups * sizeof(char *));
if (file == NULL)
file = _PATH_PW_CONF;
if ((fp = fopen(file, "r")) != NULL) {
- char buf[_UC_MAXLINE];
-
- while (fgets(buf, sizeof buf, fp) != NULL) {
- char *p = strchr(buf, '\n');
-
- if (p == NULL) { /* Line too long */
- int ch;
+ int buflen = LNBUFSZ;
+ char *buf = malloc(buflen);
+
+ nextline:
+ while (fgets(buf, buflen, fp) != NULL) {
+ char *p;
+
+ while ((p = strchr(buf, '\n')) == NULL) {
+ int l;
+ if (extendline(&buf, &buflen, buflen + LNBUFSZ) == -1) {
+ int ch;
+ while ((ch = fgetc(fp)) != '\n' && ch != EOF);
+ goto nextline; /* Ignore it */
+ }
+ l = strlen(buf);
+ if (fgets(buf + l, buflen - l, fp) == NULL)
+ break; /* Unterminated last line */
+ }
- while ((ch = fgetc(fp)) != '\n' && ch != EOF);
- } else {
+ if (p != NULL)
*p = '\0';
- if (*buf && *buf != '\n' && (p = strtok(buf, " \t\r\n=")) != NULL && *p != '#') {
- static char const toks[] = " \t\r\n,=";
- char *q = strtok(NULL, toks);
- int i = 0;
- while (i < _UC_FIELDS && strcmp(p, kwds[i]) != 0)
- ++i;
+ if (*buf && (p = strtok(buf, " \t\r\n=")) != NULL && *p != '#') {
+ static char const toks[] = " \t\r\n,=";
+ char *q = strtok(NULL, toks);
+ int i = 0;
+
+ while (i < _UC_FIELDS && strcmp(p, kwds[i]) != 0)
+ ++i;
#if debugging
- if (i == _UC_FIELDS)
- printf("Got unknown kwd `%s' val=`%s'\n", p, q ? q : "");
- else
- printf("Got kwd[%s]=%s\n", p, q);
+ if (i == _UC_FIELDS)
+ printf("Got unknown kwd `%s' val=`%s'\n", p, q ? q : "");
+ else
+ printf("Got kwd[%s]=%s\n", p, q);
#endif
- switch (i) {
- case _UC_DEFAULTPWD:
- config.default_password = boolean_val(q, 1);
- break;
- case _UC_REUSEUID:
- config.reuse_uids = boolean_val(q, 0);
- break;
- case _UC_REUSEGID:
- config.reuse_gids = boolean_val(q, 0);
- break;
- case _UC_DOTDIR:
- config.dotdir = (q == NULL || !boolean_val(q, 1))
- ? NULL : newstr(q);
- break;
- case _UC_NEWMAIL:
- config.newmail = (q == NULL || !boolean_val(q, 1))
- ? NULL : newstr(q);
- break;
- case _UC_LOGFILE:
- config.logfile = (q == NULL || !boolean_val(q, 1))
- ? NULL : newstr(q);
- break;
- case _UC_HOMEROOT:
- config.home = (q == NULL || !boolean_val(q, 1))
- ? "/home" : newstr(q);
- break;
- case _UC_SHELLPATH:
- config.shelldir = (q == NULL || !boolean_val(q, 1))
- ? "/bin" : newstr(q);
- break;
- case _UC_SHELLS:
- for (i = 0; i < _UC_MAXSHELLS && q != NULL; i++, q = strtok(NULL, toks))
- system_shells[i] = newstr(q);
- if (i > 0)
- while (i < _UC_MAXSHELLS)
- system_shells[i++] = NULL;
- break;
- case _UC_DEFAULTSHELL:
- config.shell_default = (q == NULL || !boolean_val(q, 1))
- ? (char *) bourne_shell : newstr(q);
- break;
- case _UC_DEFAULTGROUP:
- config.default_group = (q == NULL || !boolean_val(q, 1) || getgrnam(q) == NULL)
- ? NULL : newstr(q);
- break;
- case _UC_EXTRAGROUPS:
- for (i = 0; i < _UC_MAXGROUPS && q != NULL; i++, q = strtok(NULL, toks))
- default_groups[i] = newstr(q);
- if (i > 0)
- while (i < _UC_MAXGROUPS)
- default_groups[i++] = NULL;
- break;
- case _UC_DEFAULTCLASS:
- config.default_class = (q == NULL || !boolean_val(q, 1))
- ? NULL : newstr(q);
- break;
- case _UC_MINUID:
- if ((q = unquote(q)) != NULL && isdigit(*q))
- config.min_uid = (uid_t) atol(q);
- break;
- case _UC_MAXUID:
- if ((q = unquote(q)) != NULL && isdigit(*q))
- config.max_uid = (uid_t) atol(q);
- break;
- case _UC_MINGID:
- if ((q = unquote(q)) != NULL && isdigit(*q))
- config.min_gid = (gid_t) atol(q);
- break;
- case _UC_MAXGID:
- if ((q = unquote(q)) != NULL && isdigit(*q))
- config.max_gid = (gid_t) atol(q);
- break;
- case _UC_EXPIRE:
- if ((q = unquote(q)) != NULL && isdigit(*q))
- config.expire_days = atoi(q);
- break;
- case _UC_PASSWORD:
- if ((q = unquote(q)) != NULL && isdigit(*q))
- config.password_days = atoi(q);
- break;
- case _UC_FIELDS:
- case _UC_NONE:
- break;
+ switch (i) {
+ case _UC_DEFAULTPWD:
+ config.default_password = boolean_val(q, 1);
+ break;
+ case _UC_REUSEUID:
+ config.reuse_uids = boolean_val(q, 0);
+ break;
+ case _UC_REUSEGID:
+ config.reuse_gids = boolean_val(q, 0);
+ break;
+ case _UC_DOTDIR:
+ config.dotdir = (q == NULL || !boolean_val(q, 1))
+ ? NULL : newstr(q);
+ break;
+ case _UC_NEWMAIL:
+ config.newmail = (q == NULL || !boolean_val(q, 1))
+ ? NULL : newstr(q);
+ break;
+ case _UC_LOGFILE:
+ config.logfile = (q == NULL || !boolean_val(q, 1))
+ ? NULL : newstr(q);
+ break;
+ case _UC_HOMEROOT:
+ config.home = (q == NULL || !boolean_val(q, 1))
+ ? "/home" : newstr(q);
+ break;
+ case _UC_SHELLPATH:
+ config.shelldir = (q == NULL || !boolean_val(q, 1))
+ ? "/bin" : newstr(q);
+ break;
+ case _UC_SHELLS:
+ for (i = 0; i < _UC_MAXSHELLS && q != NULL; i++, q = strtok(NULL, toks))
+ system_shells[i] = newstr(q);
+ if (i > 0)
+ while (i < _UC_MAXSHELLS)
+ system_shells[i++] = NULL;
+ break;
+ case _UC_DEFAULTSHELL:
+ config.shell_default = (q == NULL || !boolean_val(q, 1))
+ ? (char *) bourne_shell : newstr(q);
+ break;
+ case _UC_DEFAULTGROUP:
+ config.default_group = (q == NULL || !boolean_val(q, 1) || getgrnam(q) == NULL)
+ ? NULL : newstr(q);
+ break;
+ case _UC_EXTRAGROUPS:
+ for (i = 0; q != NULL; q = strtok(NULL, toks)) {
+ if (extendarray(&config.groups, &config.numgroups, i + 2) != -1)
+ config.groups[i++] = newstr(q);
}
+ if (i > 0)
+ while (i < config.numgroups)
+ config.groups[i++] = NULL;
+ break;
+ case _UC_DEFAULTCLASS:
+ config.default_class = (q == NULL || !boolean_val(q, 1))
+ ? NULL : newstr(q);
+ break;
+ case _UC_MINUID:
+ if ((q = unquote(q)) != NULL && isdigit(*q))
+ config.min_uid = (uid_t) atol(q);
+ break;
+ case _UC_MAXUID:
+ if ((q = unquote(q)) != NULL && isdigit(*q))
+ config.max_uid = (uid_t) atol(q);
+ break;
+ case _UC_MINGID:
+ if ((q = unquote(q)) != NULL && isdigit(*q))
+ config.min_gid = (gid_t) atol(q);
+ break;
+ case _UC_MAXGID:
+ if ((q = unquote(q)) != NULL && isdigit(*q))
+ config.max_gid = (gid_t) atol(q);
+ break;
+ case _UC_EXPIRE:
+ if ((q = unquote(q)) != NULL && isdigit(*q))
+ config.expire_days = atoi(q);
+ break;
+ case _UC_PASSWORD:
+ if ((q = unquote(q)) != NULL && isdigit(*q))
+ config.password_days = atoi(q);
+ break;
+ case _UC_FIELDS:
+ case _UC_NONE:
+ break;
}
}
}
+ free(buf);
fclose(fp);
}
return &config;
@@ -353,7 +366,8 @@ write_userconfig(char const * file)
close(fd);
else {
int i, j, k;
- char buf[_UC_MAXLINE];
+ int len = LNBUFSZ;
+ char *buf = malloc(len);
for (i = _UC_NONE; i < _UC_FIELDS; i++) {
int quote = 1;
@@ -386,8 +400,14 @@ write_userconfig(char const * file)
val = config.shelldir;
break;
case _UC_SHELLS:
- for (j = k = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++)
- k += sprintf(buf + k, "%s\"%s\"", k ? "," : "", system_shells[j]);
+ for (j = k = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++) {
+ char lbuf[64];
+ int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", system_shells[j]);
+ if (l + k + 1 < len || extendline(&buf, &len, len + LNBUFSZ) != -1) {
+ strcpy(buf + k, lbuf);
+ k += l;
+ }
+ }
quote = 0;
break;
case _UC_DEFAULTSHELL:
@@ -397,8 +417,15 @@ write_userconfig(char const * file)
val = config.default_group ? config.default_group : "";
break;
case _UC_EXTRAGROUPS:
- for (j = k = 0; j < _UC_MAXGROUPS && default_groups[j] != NULL; j++)
- k += sprintf(buf + k, "%s\"%s\"", k ? "," : "", default_groups[j]);
+ extendarray(&config.groups, &config.numgroups, 200);
+ for (j = k = 0; j < config.numgroups && config.groups[j] != NULL; j++) {
+ char lbuf[64];
+ int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", config.groups[j]);
+ if (l + k + 1 < len || extendline(&buf, &len, len + 1024) != -1) {
+ strcpy(buf + k, lbuf);
+ k += l;
+ }
+ }
quote = 0;
break;
case _UC_DEFAULTCLASS:
@@ -445,6 +472,7 @@ write_userconfig(char const * file)
#endif
}
}
+ free(buf);
return fclose(fp) != EOF;
}
}
diff --git a/pw/pw_group.c b/pw/pw_group.c
index 8097297..a8b3c41 100644
--- a/pw/pw_group.c
+++ b/pw/pw_group.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pw_group.c,v 1.1.1.3 1996/12/10 23:59:01 joerg Exp $
+ * $Id: pw_group.c,v 1.2 1996/12/19 15:22:44 davidn Exp $
*/
#include <unistd.h>
@@ -32,6 +32,7 @@
#include "pw.h"
#include "bitmap.h"
+#include "pwupd.h"
static int print_group(struct group * grp, int pretty);
@@ -44,7 +45,8 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
struct carg *a_gid = getarg(args, 'g');
struct carg *arg;
struct group *grp = NULL;
- char *members[_UC_MAXGROUPS];
+ int grmembers = 0;
+ char **members = NULL;
static struct group fakegroup =
{
@@ -93,8 +95,11 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
if (grp == NULL) {
if (mode == M_PRINT && getarg(args, 'F')) {
+ char *fmems[1];
+ fmems[0] = NULL;
fakegroup.gr_name = a_name ? a_name->val : "nogroup";
fakegroup.gr_gid = a_gid ? (gid_t) atol(a_gid->val) : -1;
+ fakegroup.gr_mem = fmems;
return print_group(&fakegroup, getarg(args, 'P') != NULL);
}
cmderr(EX_DATAERR, "unknown group `%s'\n", a_name ? a_name->val : a_gid->val);
@@ -126,7 +131,8 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
else if (grp != NULL) /* Exists */
cmderr(EX_DATAERR, "group name `%s' already exists\n", a_name->val);
- memset(members, 0, sizeof members);
+ extendarray(&members, &grmembers, 200);
+ members[0] = NULL;
grp = &fakegroup;
grp->gr_name = pw_checkname((u_char *)a_name->val, 0);
grp->gr_passwd = "*";
@@ -188,13 +194,19 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
char *p;
struct passwd *pwd;
+ /* Make sure this is not stay NULL with -M "" */
+ extendarray(&members, &grmembers, 200);
if (arg->ch == 'm') {
- while (i < _UC_MAXGROUPS && grp->gr_mem[i] != NULL) {
- members[i] = grp->gr_mem[i];
- i++;
+ int k = 0;
+
+ while (grp->gr_mem[k] != NULL) {
+ if (extendarray(&members, &grmembers, i + 2) != -1) {
+ members[i++] = grp->gr_mem[k];
+ }
+ k++;
}
}
- for (p = strtok(arg->val, ", \t"); i < _UC_MAXGROUPS && p != NULL; p = strtok(NULL, ", \t")) {
+ for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
int j;
if ((pwd = getpwnam(p)) == NULL) {
if (!isdigit(*p) || (pwd = getpwuid((uid_t) atoi(p))) == NULL)
@@ -205,10 +217,10 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
*/
for (j = 0; j < i && strcmp(members[j], pwd->pw_name)!=0; j++)
;
- if (j == i)
+ if (j == i && extendarray(&members, &grmembers, i + 2) != -1)
members[i++] = newstr(pwd->pw_name);
}
- while (i < _UC_MAXGROUPS)
+ while (i < grmembers)
members[i++] = NULL;
grp->gr_mem = members;
}
@@ -226,6 +238,9 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
pw_log(cnf, mode, W_GROUP, "%s(%ld)", grp->gr_name, (long) grp->gr_gid);
+ if (members)
+ free(members);
+
return EXIT_SUCCESS;
}
@@ -296,17 +311,19 @@ static int
print_group(struct group * grp, int pretty)
{
if (!pretty) {
- char buf[_UC_MAXLINE];
+ int buflen = 0;
+ char *buf = NULL;
- fmtgrent(buf, grp);
+ fmtgrent(&buf, &buflen, grp);
fputs(buf, stdout);
+ free(buf);
} else {
int i;
- printf("Group Name : %-10s #%lu\n"
- " Members : ",
+ printf("Group Name: %-10s #%lu\n"
+ " Members: ",
grp->gr_name, (long) grp->gr_gid);
- for (i = 0; i < _UC_MAXGROUPS && grp->gr_mem[i]; i++)
+ for (i = 0; grp->gr_mem[i]; i++)
printf("%s%s", i ? "," : "", grp->gr_mem[i]);
fputs("\n\n", stdout);
}
diff --git a/pw/pw_user.c b/pw/pw_user.c
index 4d6131f..81d4d9f 100644
--- a/pw/pw_user.c
+++ b/pw/pw_user.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pw_user.c,v 1.6 1996/12/19 15:22:45 davidn Exp $
+ * $Id: pw_user.c,v 1.7 1996/12/20 10:45:39 davidn Exp $
*/
#include <unistd.h>
@@ -51,6 +51,7 @@ static char *pw_shellpolicy(struct userconf * cnf, struct cargs * args, char
static char *pw_password(struct userconf * cnf, struct cargs * args, char const * user);
static char *shell_path(char const * path, char *shells[], char *sh);
static void rmat(uid_t uid);
+static void rmskey(char const * name);
/*-
* -C config configuration file
@@ -93,7 +94,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
struct passwd *pwd = NULL;
struct group *grp;
struct stat st;
- char line[MAXPWLINE];
+ char line[_PASSWORD_LEN+1];
static struct passwd fakeuser =
{
@@ -152,14 +153,15 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if ((arg = getarg(args, 'G')) != NULL && arg->val) {
int i = 0;
- for (p = strtok(arg->val, ", \t"); i < _UC_MAXGROUPS && p != NULL; p = strtok(NULL, ", \t")) {
+ for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
if ((grp = getgrnam(p)) == NULL) {
if (!isdigit(*p) || (grp = getgrgid((gid_t) atoi(p))) == NULL)
cmderr(EX_NOUSER, "group `%s' does not exist\n", p);
}
- cnf->groups[i++] = newstr(grp->gr_name);
+ if (extendarray(&cnf->groups, &cnf->numgroups, i + 2) != -1)
+ cnf->groups[i++] = newstr(grp->gr_name);
}
- while (i < _UC_MAXGROUPS)
+ while (i < cnf->numgroups)
cnf->groups[i++] = NULL;
}
if ((arg = getarg(args, 'k')) != NULL) {
@@ -252,6 +254,12 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
cmderr(EX_DATAERR, "cannot remove user 'root'\n");
/*
+ * Remove skey record from /etc/skeykeys
+ */
+
+ rmskey(pwd->pw_name);
+
+ /*
* Remove crontabs
*/
sprintf(file, "/var/cron/tabs/%s", pwd->pw_name);
@@ -347,6 +355,14 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (getarg(args, 'L'))
pwd->pw_class = cnf->default_class;
+ if ((arg = getarg(args, 'd')) != NULL) {
+ if (stat(pwd->pw_dir = arg->val, &st) == -1) {
+ if (getarg(args, 'm') == NULL && strcmp(pwd->pw_dir, "/nonexistent") != 0)
+ fprintf(stderr, "WARNING: home `%s' does not exist\n", pwd->pw_dir);
+ } else if (!S_ISDIR(st.st_mode))
+ fprintf(stderr, "WARNING: home `%s' is not a directory\n", pwd->pw_dir);
+ }
+
if ((arg = getarg(args, 'w')) != NULL && getarg(args, 'h') == NULL)
pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name);
@@ -900,12 +916,12 @@ print_user(struct passwd * pwd, int pretty)
strftime(acexpire, sizeof acexpire, "%c", tptr);
if (pwd->pw_change > (time_t)9 && (tptr = localtime(&pwd->pw_change)) != NULL)
strftime(pwexpire, sizeof pwexpire, "%c", tptr);
- printf("Login Name : %-10s #%-22ld Group : %-10s #%ld\n"
- " Full Name : %s\n"
- " Home : %-32.32s Class : %s\n"
- " Shell : %-32.32s Office : %s\n"
- "Work Phone : %-32.32s Home Phone : %s\n"
- "Acc Expire : %-32.32s Pwd Expire : %s\n",
+ printf("Login Name: %-10s #%-16ld Group: %-10s #%ld\n"
+ " Full Name: %s\n"
+ " Home: %-26.26s Class: %s\n"
+ " Shell: %-26.26s Office: %s\n"
+ "Work Phone: %-26.26s Home Phone: %s\n"
+ "Acc Expire: %-26.26s Pwd Expire: %s\n",
pwd->pw_name, (long) pwd->pw_uid,
grp ? grp->gr_name : "(invalid)", (long) pwd->pw_gid,
uname, pwd->pw_dir, pwd->pw_class,
@@ -916,11 +932,11 @@ print_user(struct passwd * pwd, int pretty)
while ((grp=getgrent()) != NULL)
{
int i = 0;
- while (i < _UC_MAXGROUPS && grp->gr_mem[i] != NULL)
+ while (grp->gr_mem[i] != NULL)
{
if (strcmp(grp->gr_mem[i], pwd->pw_name)==0)
{
- printf(j++ == 0 ? " Groups : %s" : ",%s", grp->gr_name);
+ printf(j++ == 0 ? " Groups: %s" : ",%s", grp->gr_name);
break;
}
++i;
@@ -977,3 +993,40 @@ rmat(uid_t uid)
closedir(d);
}
}
+
+static void
+rmskey(char const * name)
+{
+ static const char etcskey[] = "/etc/skeykeys";
+ static const char newskey[] = "/etc/skeykeys.new";
+ int done = 0;
+ FILE *infp = fopen(etcskey, "r");
+
+ if (infp != NULL) {
+ int fd = open(newskey, O_RDWR|O_CREAT|O_TRUNC, 0644);
+
+ if (fd != -1) {
+ FILE * outfp = fdopen(fd, "w");
+ int length = strlen(name);
+ char tmp[1024];
+
+ while (fgets(tmp, sizeof tmp, infp) != NULL) {
+ if (strncmp(name, tmp, length) == 0 && isspace(tmp[length]))
+ ++done; /* Found a key */
+ else
+ fputs(tmp, outfp);
+ }
+ /*
+ * If we got an error of any sort, don't update!
+ */
+ if (fclose(outfp) == EOF || ferror(infp))
+ done = 0;
+ }
+ fclose(infp);
+ if (!done)
+ remove(newskey);
+ else
+ rename(newskey, etcskey);
+ }
+}
+
diff --git a/pw/pwupd.c b/pw/pwupd.c
index 149d239..fb56dac 100644
--- a/pw/pwupd.c
+++ b/pw/pwupd.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pwupd.c,v 1.1.1.2 1996/12/09 23:55:27 joerg Exp $
+ * $Id: pwupd.c,v 1.1.1.3 1996/12/10 23:59:02 joerg Exp $
*/
#include <stdio.h>
@@ -118,7 +118,7 @@ pw_update(struct passwd * pwd, char const * user, int mode)
{ /* No -c */
#endif
char pfx[32];
- char pwbuf[MAXPWLINE];
+ char pwbuf[PWBUFSZ];
int l = sprintf(pfx, "%s:", user);
/*
diff --git a/pw/pwupd.h b/pw/pwupd.h
index 54324f8..457a91b 100644
--- a/pw/pwupd.h
+++ b/pw/pwupd.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pwupd.h,v 1.1.1.1 1996/12/09 14:05:35 joerg Exp $
+ * $Id: pwupd.h,v 1.1.1.2 1996/12/10 23:59:03 joerg Exp $
*/
#ifndef _PWUPD_H_
@@ -60,20 +60,22 @@ int delpwent __P((struct passwd * pwd));
int chgpwent __P((char const * login, struct passwd * pwd));
int fmtpwent __P((char *buf, struct passwd * pwd));
int fmtpwentry __P((char *buf, struct passwd * pwd, int type));
+
int addgrent __P((struct group * grp));
int delgrent __P((struct group * grp));
int chggrent __P((char const * name, struct group * grp));
-int fmtgrent __P((char *buf, struct group * grp));
-int fmtgrentry __P((char *buf, struct group * grp, int type));
+int fmtgrent __P((char **buf, int * buflen, struct group * grp));
+int fmtgrentry __P((char **buf, int * buflen, struct group * grp, int type));
int editgroups __P((char *name, char **groups));
__END_DECLS
-#define MAXGROUPS 200
-#define MAXPWLINE 1024
+#define PWBUFSZ 1024
__BEGIN_DECLS
void copymkdir __P((char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid));
void rm_r __P((char const * dir, uid_t uid));
+int extendline __P((char **buf, int *buflen, int needed));
+int extendarray __P((char ***buf, int *buflen, int needed));
__END_DECLS
#endif /* !_PWUPD_H */