useradd.c revision 7fc68ddf208200ddeef6f09e60ab0fbf0e919fea
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2013 Gary Mills
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright (c) 2013 RackTop Systems.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <userdefs.h>
#include <errno.h>
#include <project.h>
#include <unistd.h>
#include <user_attr.h>
#include <libcmdutils.h>
#include "users.h"
#include "messages.h"
#include "userdisp.h"
#include "funcs.h"
/*
* useradd [-u uid [-o] | -g group | -G group [[, group]...]
* | -d dir [-m [-z|Z]]
* | -s shell | -c comment | -k skel_dir | -b base_dir] ]
* [ -A authorization [, authorization ...]]
* [ -P profile [, profile ...]]
* [ -K key=value ]
* [ -R role [, role ...]] [-p project [, project ...]] login
* useradd -D [ -g group ] [ -b base_dir | -f inactive | -e expire |
* -s shell | -k skel_dir ]
* [ -A authorization [, authorization ...]]
* [ -P profile [, profile ...]] [ -K key=value ]
* [ -R role [, role ...]] [-p project [, project ...]] login
*
* This command adds new user logins to the system. Arguments are:
*
* uid - an integer
* group - an existing group's integer ID or char string name
* dir - home directory
* shell - a program to be used as a shell
* comment - any text string
* skel_dir - a skeleton directory
* base_dir - a directory
* login - a string of printable chars except colon(:)
* authorization - One or more comma separated authorizations defined
* in auth_attr(4).
* profile - One or more comma separated execution profiles defined
* in prof_attr(4)
* role - One or more comma-separated role names defined in user_attr(4)
* project - One or more comma-separated project names or numbers
*
*/
extern void dispusrdef();
static void cleanup();
extern int check_perm(), valid_expire();
extern int edit_project();
extern int **valid_lgroup();
extern projid_t **valid_lproject();
extern void update_def(struct userdefs *);
extern void import_def(struct userdefs *);
extern int get_default_zfs_flags();
static char *logname; /* login name to add */
char *cmdname;
static long inact; /* inactive days */
typedef enum {
BASEDIR = 0,
} path_opt_t;
static void valid_input(path_opt_t, const char *);
int
int argc;
char *argv[];
{
char *ptr; /* loc in a str, may be set by strtol */
char mybuf[PROJECT_BUFSZ];
int warning;
int busy = 0;
char **nargv; /* arguments for execvp of passmgmt */
int argindex; /* argument index into nargv */
int zfs_flags = 0; /* create_home flags */
if (geteuid() != 0) {
}
opterr = 0; /* no print errors from getopt */
"b:c:Dd:e:f:G:g:k:mzZop:s:u:A:P:R:K:")) != EOF)
switch (ch) {
case 'b':
break;
case 'c':
break;
case 'D':
Dflag++;
break;
case 'd':
break;
case 'e':
break;
case 'f':
break;
case 'G':
break;
case 'g':
break;
case 'k':
break;
case 'm':
mflag++;
break;
case 'o':
oflag++;
break;
case 'p':
break;
case 's':
break;
case 'u':
break;
case 'Z':
Zflag++;
break;
case 'z':
zflag++;
break;
case 'A':
break;
case 'P':
break;
case 'R':
}
break;
case 'K':
break;
default:
case '?':
else
}
else
}
/* get defaults for adding new users */
if (Dflag) {
/* DISPLAY mode */
/* check syntax */
else
}
else
}
/* Group must be an existing group */
case INVALID:
/*NOTREACHED*/
case TOOBIG:
/*NOTREACHED*/
case RESERVED:
case UNIQUE:
}
if (warning)
}
/* project must be an existing project */
case INVALID:
/*NOTREACHED*/
case TOOBIG:
/*NOTREACHED*/
case UNIQUE:
}
if (warning)
}
/* base_dir must be an existing directory */
}
/* inactivity period is an integer */
/* convert inactstr to integer */
"inactivity period");
}
}
/* expiration string is a date, newer than today */
if (*expirestr) {
== INVALID) {
"expiration date");
}
} else
/* Unset the expiration date */
}
}
}
/* change defaults for useradd */
}
/* Now, display */
}
/* ADD mode */
/* check syntax */
else
}
case INVALID:
/*NOTREACHED*/
case NOTUNIQUE:
/*NOTREACHED*/
case LONGNAME:
/*NOTREACHED*/
}
if (warning)
/* convert uidstr to integer */
errno = 0;
}
case NOTUNIQUE:
if (!oflag) {
/* override not specified */
}
break;
case RESERVED:
break;
case TOOBIG:
break;
}
} else {
}
}
case INVALID:
/*NOTREACHED*/
case TOOBIG:
/*NOTREACHED*/
case RESERVED:
case UNIQUE:
/*NOTREACHED*/
}
if (warning)
if (!*grps)
/* ignore -G "" */
grps = (char *)0;
}
if (! *projects)
projects = (char *)0;
}
/* if base_dir is provided, check its validity; otherwise default */
else
/* set homedir to home directory made from base_dir */
} else
if (mflag) {
/* Does home dir. already exist? */
/* directory exists - don't try to create */
mflag = 0;
}
}
/*
* if shell, skel_dir are provided, check their validity.
* Otherwise default.
*/
else
else
/* convert inactstr to integer */
}
/* expiration string is a date, newer than today */
if (*expirestr) {
}
} else
/* Unset the expiration date */
expirestr = (char *)0;
/* must now call passmgmt */
/* set up arguments to passmgmt in nargv array */
argindex = 0;
/* comment */
}
/* flags for home directory */
/* set gid flag */
/* shell */
/* set inactive */
/* set expiration date */
}
/* set uid flag */
if (nkeys > 1)
/* finally - login name */
/* set the last to null */
/* now call passmgmt */
ret = PEX_FAILED;
/*
* If call_passmgmt fails for any reason other than PEX_BADUID, exit
* is invoked with an appropriate error message. If PEX_BADUID is
* returned, then if the user specified the ID, exit is invoked
* with an appropriate error message. Otherwise we try to pick a
* different ID and try again. If we run out of IDs, i.e. no more
* users can be created, then -1 is returned and we terminate via exit.
* If PEX_BUSY is returned we increment a count, since we will stop
* trying if PEX_BUSY reaches 3. For PEX_SUCCESS we immediately
* terminate the loop.
*/
case PEX_SUCCESS:
break;
case PEX_BUSY:
busy++;
break;
case PEX_HOSED_FILES:
break;
case PEX_SYNTAX:
case PEX_BADARG:
/* should NEVER occur that passmgmt usage is wrong */
else
break;
case PEX_BADUID:
/*
* The uid has been taken. If it was specified by a
* user, then we must fail. Otherwise, keep trying
* to get a good uid until we run out of IDs.
*/
} else {
"user id");
}
}
break;
case PEX_BADNAME:
/* invalid loname */
break;
default:
break;
}
}
if (busy == 3) {
}
/* add group entry */
}
/* update project database */
}
/* create home directory */
if (mflag) {
zfs_flags |= MANAGE_ZFS;
else if (Zflag)
zfs_flags &= ~MANAGE_ZFS;
}
if (ret != EX_SUCCESS) {
0);
}
return (ret);
}
static void
char *logname;
{
char *nargv[4];
switch (call_passmgmt(nargv)) {
case PEX_SUCCESS:
break;
case PEX_SYNTAX:
/* should NEVER occur that passmgmt usage is wrong */
else
break;
case PEX_BADUID:
/* uid is used - shouldn't happen but print message anyway */
break;
case PEX_BADNAME:
/* invalid loname */
break;
default:
break;
}
}
/* Check the validity for shell, base_dir and skel_dir */
void
{
}
}
}
} else {
}
}
}