yppasswdd.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <syslog.h>
#include <crypt.h>
#include <errno.h>
#include <tiuser.h>
#include <netdir.h>
#include <pwd.h>
#include <shadow.h>
#include <sys/resource.h>
#include <rpc/pmap_clnt.h>
#include <rpcsvc/yppasswd.h>
#include <netconfig.h>
#include <deflt.h>
/* N2L includes */
#include <ndbm.h>
#include "shim.h"
#include "yptol.h"
/* must match sizes in passwd */
#define STRSIZE 100
#define DEFDIR "/etc/"
#define MYPASSWD "passwd"
#define MYSHADOW "shadow"
#define DEFAULT_YPPASSWDD "/etc/default/yppasswdd"
#define YPPASSWDD_STR "check_restricted_shell_name=1"
/* The guts are in there */
extern changepasswd(SVCXPRT *);
extern char *getusershell(void);
extern void setusershell(void);
extern void endusershell(void);
int Argc;
char **Argv;
int mflag; /* do a make */
int Mstart;
int single = 0;
int nogecos = 0;
int noshell = 0;
int nopw = 0;
int useadjunct = 0;
int useshadow = 0;
/* These are the various reasons we might exit. */
enum exitstat {
};
static char err_usage[] =
"Usage:\n"
" rpc.yppasswdd [-D directory | passwd [passwd.adjunct]]\n"
" [-nopw] [-nogecos]\n"
" [-noshell] [-m arg1 arg2 ...]\n"
"where\n"
" passwd.adjunct files are found (/etc by default)\n"
" Alternatively, the old 4.1.x syntax is supported where\n"
" passwd is the path to the passwd file\n"
" passwd.adjunct is the patch to the passwd.adjunct file\n"
" NOTES:\n"
" 1. The -D option and the passwd/passwd.adjunct arguments are\n"
" mutually exclusive\n"
" 2. The old syntax deprecated and will be removed in a future\n"
" release\n"
" 3. A shadow file found in the same directory as the passwd\n"
" will be assumed to contain the password information\n\n"
" arguments after -m are passed to make(1S) after password changes\n"
" -nopw passwords may not be changed remotely using passwd\n"
" -nogecos full name may not be changed remotely using passwd or chfn\n"
" -noshell shell may not be changed remotely using passwd or chsh\n";
int
{
int errorflag;
int dfexcl; /* -D or files, not both flag */
int connmaxrec = RPC_MAXDATASIZE;
"ignoring -m option",
argv[0]);
else {
mflag++;
Mstart = i;
break;
}
switch (dfexcl) {
case 0:
if (++i < argc) {
} else {
"/security/passwd.adjunct");
}
dfexcl++;
} else {
"rpc.yppasswdd: -D option requires a "
"directory argument\n");
errorflag++;
}
break;
case 1:
"rpc.yppasswdd: cannot specify passwd/"
"passwd.adjunct pathnames AND use -D\n");
errorflag++;
dfexcl++;
break;
default:
break;
}
/* -single: Allow user to change only one of password, */
/* shell, or full name at a time. (WHY?) */
/* else if (strcmp(argv[i], "-single") == 0) */
/* single = 1; */
/* else if (strcmp(argv[i], "-nosingle") == 0) */
/* single = 0; */
nogecos = 1;
nopw = 1;
noshell = 1;
else if (argv[i][0] != '-') {
/*
* If we find a shadow file, we warn that we're
* using it in addition to warning that the user
* it using a deprecated syntax.
*/
errorflag++;
switch (dfexcl) {
case 0:
"rpc.yppasswdd: specifying the password file"
" on the command line is \n"
" obsolete, "
"consider using the -D option instead.\n");
"rpc.yppasswdd: found a shadow file in "
"the same directory as %s\n"
" It will be used.\n",
}
"rpc.yppasswdd: adjunct file %s "
"not found\n",
}
}
dfexcl++;
break;
case 1:
"rpc.yppasswdd: cannot specify passwd/"
"passwd.adjunct pathnames AND use -D\n");
dfexcl++;
break;
default:
break;
}
} else {
errorflag++;
"rpc.yppasswdd: unrecognized option %s ignored\n",
argv[i]);
}
}
if (errorflag)
if (exitstatus)
}
useshadow = 1;
} else {
/* We don't demand a shadow file unless we're looking at /etc */
}
}
/* using an adjunct file */
useadjunct = 1;
}
exitstatus = Echdir;
}
if (exitstatus)
if (errorflag)
/*
* Initialize locking system.
* This is required for N2L version which accesses the DBM files.
* For the non N2L version this sets up some locking which, since non
* N2L mode does not access the DBM files, will be unused.
*
* This also sets up yptol_mode.
*/
if (!init_lock_system(TRUE)) {
"rpc.yppasswdd: Cant initialize locking system\n");
}
#ifndef DEBUG
closefrom(3);
#endif
if (yptol_mode) {
if (stat == 1) {
" inactive.\n");
} else if (stat != 0) {
" mapping error.\n");
}
}
#ifndef DEBUG
/* Wack umask that we inherited from parent */
umask(0);
/* Be a midwife to ourselves */
if (fork())
/* Disassociation is hard to do, la la la */
setpgrp();
setsid();
/* Ignore stuff */
/*
* Just in case that wasn't enough, let's fork
* again. (per Stevens).
*/
if (fork())
/*
* We need stdin, stdout, and stderr later when we
* fork a make(1).
*/
#endif
/*
* Set non-blocking mode and maximum record size for
* connection oriented RPC transports.
*/
}
}
}
if (tli4 != -1) {
netdir_sperror());
}
}
if (tli6 != -1) {
netdir_sperror());
}
}
#ifdef DEBUG
{
int i, tli[2];
int state;
}
}
switch (state) {
case T_UNBND:
break;
case T_IDLE:
break;
case T_INREL:
"other side wants to release\n");
break;
case T_INCON:
break;
case T_DATAXFER:
break;
default:
state);
}
}
}
#endif
if (tli4 != -1) {
nconf4);
} else {
transp4 = 0;
}
if (tli6 != -1) {
nconf6);
} else {
transp6 = 0;
}
}
}
}
/*
* Create a loopback RPC service for secure authentication of local
* principals -- we need this for accepting passwd updates from
* root on the master server.
*/
}
"yppasswdd: couldn't create an loopback RPC server\n");
}
boilerplate, nconfl)) {
}
svc_run();
return (Esvcrun_ret);
/* NOTREACHED */
}
static void
{
case NULLPROC:
"yppasswdd: couldn't reply to RPC call\n");
break;
case YPPASSWDPROC_UPDATE:
if (yptol_mode)
else
break;
}
}
int
{
char c;
return (0);
while (c = *str++) {
if (iscntrl(c))
return (0);
}
return (1);
}
{
if ((defopen(DEFAULT_YPPASSWDD)) == 0) {
if (cp)
cp++;
else
if (*cp == 'r') {
"yppasswdd: cannot change "
"from restricted shell %s\n",
pw_shell);
return (0);
}
}
}
break;
pw_shell);
endusershell();
return (0);
}
if (arg != 0) {
} else {
endusershell();
return (0);
}
/*
* Allow user to give shell name w/o preceding pathname.
*/
setusershell();
if (newshell[0] == '/') {
} else {
if (cp == 0)
else
cp++;
}
break;
}
if (valid == 0) {
"%s is unacceptable as a new shell.\n",
newshell);
endusershell();
return (0);
}
}
endusershell();
return (0);
}
endusershell();
return (1);
}
static void
{
}