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.
This commit is contained in:
David Nugent 1996-12-21 15:35:45 +00:00
parent 33703c0825
commit 0970881ff6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=20747
9 changed files with 464 additions and 282 deletions

View File

@ -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];
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);
while (fgets(line, sizeof(line), infp) != NULL) {
char *p = strchr(line, '\n');
if (line == NULL || outl == NULL || mems == NULL) {
mem_abort:
rc = 0;
} else {
while (fgets(line, linelen, infp) != NULL) {
char *p;
int l;
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;
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;
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;
for (i = mno; i < MAXGROUPS; i++)
mems[i] = NULL;
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;
/*
* Delete from group, or add to group?
*/
if (groups == NULL || isingroup(grp.gr_name, groups) == -1) { /* Delete */
int idx;
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;
if (groups == NULL || isingroup(grp.gr_name, groups) == -1) { /* Delete */
int idx;
setpwent();
while ((pwd = getpwent()) != NULL && pwd->pw_gid != grp.gr_gid);
endpwent();
if (pwd == NULL) /* No members at all */
continue; /* Drop the group */
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);
}
fputs(outl, outfp);
}
if (fflush(outfp) != EOF) {
rc = 1;
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);
/*
* 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));
/*
* 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);

View File

@ -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>
@ -38,6 +38,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)
{
@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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];
int buflen = LNBUFSZ;
char *buf = malloc(buflen);
while (fgets(buf, sizeof buf, fp) != NULL) {
char *p = strchr(buf, '\n');
nextline:
while (fgets(buf, buflen, fp) != NULL) {
char *p;
if (p == NULL) { /* Line too long */
int ch;
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;
}
}

View File

@ -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);
}

View File

@ -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) {
@ -251,6 +253,12 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (strcmp(pwd->pw_name, "root") == 0)
cmderr(EX_DATAERR, "cannot remove user 'root'\n");
/*
* Remove skey record from /etc/skeykeys
*/
rmskey(pwd->pw_name);
/*
* Remove crontabs
*/
@ -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);
}
}

View File

@ -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);
/*

View File

@ -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 */