New pw -R rootdir option
This allows to set an alternate root directory in which the users/groups will be manipulated Requested by: gjb, ian Tested by: gjb
This commit is contained in:
parent
23c9098b2a
commit
ac72be285f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=283961
@ -56,7 +56,7 @@ static const char *Combo2[] = {
|
||||
|
||||
struct pwf PWF =
|
||||
{
|
||||
0,
|
||||
PWF_REGULAR,
|
||||
setpwent,
|
||||
endpwent,
|
||||
getpwent,
|
||||
@ -71,7 +71,7 @@ struct pwf PWF =
|
||||
};
|
||||
struct pwf VPWF =
|
||||
{
|
||||
1,
|
||||
PWF_ALT,
|
||||
vsetpwent,
|
||||
vendpwent,
|
||||
vgetpwent,
|
||||
@ -99,24 +99,27 @@ main(int argc, char *argv[])
|
||||
char *config = NULL;
|
||||
struct userconf *cnf;
|
||||
struct stat st;
|
||||
char arg;
|
||||
struct carg *carg;
|
||||
char *etcpath = NULL;
|
||||
|
||||
static const char *opts[W_NUM][M_NUM] =
|
||||
{
|
||||
{ /* user */
|
||||
"V:C:qn:u:c:d:e:p:g:G:mM:k:s:oL:i:w:h:H:Db:NPy:Y",
|
||||
"V:C:qn:u:rY",
|
||||
"V:C:qn:u:c:d:e:p:g:G:mM:l:k:s:w:L:h:H:FNPY",
|
||||
"V:C:qn:u:FPa7",
|
||||
"V:C:q",
|
||||
"V:C:q",
|
||||
"V:C:q"
|
||||
"R:V:C:qn:u:c:d:e:p:g:G:mM:k:s:oL:i:w:h:H:Db:NPy:Y",
|
||||
"R:V:C:qn:u:rY",
|
||||
"R:V:C:qn:u:c:d:e:p:g:G:mM:l:k:s:w:L:h:H:FNPY",
|
||||
"R:V:C:qn:u:FPa7",
|
||||
"R:V:C:q",
|
||||
"R:V:C:q",
|
||||
"R:V:C:q"
|
||||
},
|
||||
{ /* grp */
|
||||
"V:C:qn:g:h:H:M:opNPY",
|
||||
"V:C:qn:g:Y",
|
||||
"V:C:qn:d:g:l:h:H:FM:m:NPY",
|
||||
"V:C:qn:g:FPa",
|
||||
"V:C:q"
|
||||
"R:V:C:qn:g:h:H:M:opNPY",
|
||||
"R:V:C:qn:g:Y",
|
||||
"R:V:C:qn:d:g:l:h:H:FM:m:NPY",
|
||||
"R:V:C:qn:g:FPa",
|
||||
"R:V:C:q"
|
||||
}
|
||||
};
|
||||
|
||||
@ -141,7 +144,8 @@ main(int argc, char *argv[])
|
||||
/*
|
||||
* Special case, allow pw -V<dir> <operation> [args] for scripts etc.
|
||||
*/
|
||||
if (argv[1][1] == 'V') {
|
||||
arg = argv[1][1];
|
||||
if (arg == 'V' || arg == 'R') {
|
||||
optarg = &argv[1][2];
|
||||
if (*optarg == '\0') {
|
||||
if (stat(argv[2], &st) != 0)
|
||||
@ -155,7 +159,7 @@ main(int argc, char *argv[])
|
||||
++argv;
|
||||
--argc;
|
||||
}
|
||||
addarg(&arglist, 'V', optarg);
|
||||
addarg(&arglist, arg, optarg);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
@ -217,19 +221,29 @@ main(int argc, char *argv[])
|
||||
|
||||
config = getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL;
|
||||
|
||||
if (getarg(&arglist, 'V') != NULL) {
|
||||
char * etcpath = getarg(&arglist, 'V')->val;
|
||||
if (*etcpath) {
|
||||
if (config == NULL) { /* Only override config location if -C not specified */
|
||||
asprintf(&config, "%s/pw.conf", etcpath);
|
||||
if (config == NULL)
|
||||
errx(EX_OSERR, "out of memory");
|
||||
}
|
||||
memcpy(&PWF, &VPWF, sizeof PWF);
|
||||
setpwdir(etcpath);
|
||||
setgrdir(etcpath);
|
||||
}
|
||||
if ((carg = getarg(&arglist, 'R')) != NULL) {
|
||||
asprintf(&etcpath, "%s/etc", carg->val);
|
||||
if (etcpath == NULL)
|
||||
errx(EX_OSERR, "out of memory");
|
||||
}
|
||||
if (etcpath == NULL && (carg = getarg(&arglist, 'V')) != NULL) {
|
||||
etcpath = strdup(carg->val);
|
||||
if (etcpath == NULL)
|
||||
errx(EX_OSERR, "out of memory");
|
||||
}
|
||||
if (etcpath && *etcpath) {
|
||||
if (config == NULL) { /* Only override config location if -C not specified */
|
||||
asprintf(&config, "%s/pw.conf", etcpath);
|
||||
if (config == NULL)
|
||||
errx(EX_OSERR, "out of memory");
|
||||
}
|
||||
setpwdir(etcpath);
|
||||
setgrdir(etcpath);
|
||||
memcpy(&PWF, &VPWF, sizeof PWF);
|
||||
if (getarg(&arglist, 'R'))
|
||||
PWF._altdir = PWF_ROOTDIR;
|
||||
}
|
||||
free(etcpath);
|
||||
|
||||
/*
|
||||
* Now, let's do the common initialisation
|
||||
@ -303,6 +317,7 @@ cmdhelp(int mode, int which)
|
||||
{
|
||||
"usage: pw useradd [name] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-C config configuration file\n"
|
||||
"\t-q quiet operation\n"
|
||||
" Adding users:\n"
|
||||
@ -325,6 +340,7 @@ cmdhelp(int mode, int which)
|
||||
"\t-N no update\n"
|
||||
" Setting defaults:\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-D set user defaults\n"
|
||||
"\t-b dir default home root dir\n"
|
||||
"\t-e period default expiry period\n"
|
||||
@ -341,12 +357,14 @@ cmdhelp(int mode, int which)
|
||||
"\t-y path set NIS passwd file path\n",
|
||||
"usage: pw userdel [uid|name] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-n name login name\n"
|
||||
"\t-u uid user id\n"
|
||||
"\t-Y update NIS maps\n"
|
||||
"\t-r remove home & contents\n",
|
||||
"usage: pw usermod [uid|name] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-C config configuration file\n"
|
||||
"\t-q quiet operation\n"
|
||||
"\t-F force add if no user\n"
|
||||
@ -370,6 +388,7 @@ cmdhelp(int mode, int which)
|
||||
"\t-N no update\n",
|
||||
"usage: pw usershow [uid|name] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-n name login name\n"
|
||||
"\t-u uid user id\n"
|
||||
"\t-F force print\n"
|
||||
@ -378,6 +397,7 @@ cmdhelp(int mode, int which)
|
||||
"\t-7 print in v7 format\n",
|
||||
"usage: pw usernext [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-C config configuration file\n"
|
||||
"\t-q quiet operation\n",
|
||||
"usage pw: lock [switches]\n"
|
||||
@ -392,6 +412,7 @@ cmdhelp(int mode, int which)
|
||||
{
|
||||
"usage: pw groupadd [group|gid] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-C config configuration file\n"
|
||||
"\t-q quiet operation\n"
|
||||
"\t-n group group name\n"
|
||||
@ -402,11 +423,13 @@ cmdhelp(int mode, int which)
|
||||
"\t-N no update\n",
|
||||
"usage: pw groupdel [group|gid] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-n name group name\n"
|
||||
"\t-g gid group id\n"
|
||||
"\t-Y update NIS maps\n",
|
||||
"usage: pw groupmod [group|gid] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-C config configuration file\n"
|
||||
"\t-q quiet operation\n"
|
||||
"\t-F force add if not exists\n"
|
||||
@ -420,6 +443,7 @@ cmdhelp(int mode, int which)
|
||||
"\t-N no update\n",
|
||||
"usage: pw groupshow [group|gid] [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-n name group name\n"
|
||||
"\t-g gid group id\n"
|
||||
"\t-F force print\n"
|
||||
@ -427,6 +451,7 @@ cmdhelp(int mode, int which)
|
||||
"\t-a print all accounting groups\n",
|
||||
"usage: pw groupnext [switches]\n"
|
||||
"\t-V etcdir alternate /etc location\n"
|
||||
"\t-R rootir alternate root directory\n"
|
||||
"\t-C config configuration file\n"
|
||||
"\t-q quiet operation\n"
|
||||
}
|
||||
|
@ -63,6 +63,28 @@ static char *shell_path(char const * path, char *shells[], char *sh);
|
||||
static void rmat(uid_t uid);
|
||||
static void rmopie(char const * name);
|
||||
|
||||
static void
|
||||
create_and_populate_homedir(int mode, struct cargs *args, struct passwd *pwd,
|
||||
struct userconf *cnf)
|
||||
{
|
||||
char *homedir, *dotdir;
|
||||
struct carg *arg;
|
||||
|
||||
homedir = dotdir = NULL;
|
||||
|
||||
if ((arg = getarg(args, 'R'))) {
|
||||
asprintf(&homedir, "%s/%s", arg->val, pwd->pw_dir);
|
||||
if (homedir == NULL)
|
||||
errx(EX_OSERR, "out of memory");
|
||||
asprintf(&dotdir, "%s/%s", arg->val, cnf->dotdir);
|
||||
}
|
||||
|
||||
copymkdir(homedir ? homedir : pwd->pw_dir, dotdir ? dotdir: cnf->dotdir,
|
||||
cnf->homemode, pwd->pw_uid, pwd->pw_gid);
|
||||
pw_log(cnf, mode, W_USER, "%s(%u) home %s made", pwd->pw_name,
|
||||
pwd->pw_uid, pwd->pw_dir);
|
||||
}
|
||||
|
||||
/*-
|
||||
* -C config configuration file
|
||||
* -q quiet operation
|
||||
@ -108,6 +130,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
|
||||
struct group *grp;
|
||||
struct stat st;
|
||||
char line[_PASSWORD_LEN+1];
|
||||
char path[MAXPATHLEN];
|
||||
FILE *fp;
|
||||
char *dmode_c;
|
||||
void *set = NULL;
|
||||
@ -451,7 +474,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
|
||||
|
||||
pw_log(cnf, mode, W_USER, "%s(%u) account removed", a_name->val, uid);
|
||||
|
||||
if (!PWALTDIR()) {
|
||||
if (PWALTDIR()) {
|
||||
/*
|
||||
* Remove mail file
|
||||
*/
|
||||
@ -800,11 +823,13 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
|
||||
* doesn't hurt anything to create the empty mailfile
|
||||
*/
|
||||
if (mode == M_ADD) {
|
||||
if (!PWALTDIR()) {
|
||||
snprintf(line, sizeof(line), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
|
||||
close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents &
|
||||
if (PWALTDIR() != PWF_ALT) {
|
||||
arg = getarg(args, 'R');
|
||||
snprintf(path, sizeof(path), "%s%s/%s",
|
||||
arg ? arg->val : "", _PATH_MAILDIR, pwd->pw_name);
|
||||
close(open(path, O_RDWR | O_CREAT, 0600)); /* Preserve contents &
|
||||
* mtime */
|
||||
chown(line, pwd->pw_uid, pwd->pw_gid);
|
||||
chown(path, pwd->pw_uid, pwd->pw_gid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -813,12 +838,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
|
||||
* that this also `works' for editing users if -m is used, but
|
||||
* existing files will *not* be overwritten.
|
||||
*/
|
||||
if (!PWALTDIR() && getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) {
|
||||
copymkdir(pwd->pw_dir, cnf->dotdir, cnf->homemode, pwd->pw_uid, pwd->pw_gid);
|
||||
pw_log(cnf, mode, W_USER, "%s(%u) home %s made",
|
||||
pwd->pw_name, pwd->pw_uid, pwd->pw_dir);
|
||||
}
|
||||
|
||||
if (PWALTDIR() != PWF_ALT && getarg(args, 'm') != NULL && pwd->pw_dir &&
|
||||
*pwd->pw_dir == '/' && pwd->pw_dir[1])
|
||||
create_and_populate_homedir(mode, args, pwd, cnf);
|
||||
|
||||
/*
|
||||
* Finally, send mail to the new user as well, if we are asked to
|
||||
|
@ -71,6 +71,10 @@ extern struct pwf VPWF;
|
||||
#define GETGRGID(gid) PWF._getgrgid(gid)
|
||||
#define GETGRNAM(nam) PWF._getgrnam(nam)
|
||||
|
||||
#define PWF_REGULAR 0
|
||||
#define PWF_ALT 1
|
||||
#define PWF_ROOTDIR 2
|
||||
|
||||
#define PWALTDIR() PWF._altdir
|
||||
#ifndef _PATH_PWD
|
||||
#define _PATH_PWD "/etc"
|
||||
|
Loading…
Reference in New Issue
Block a user