nisaddcred.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 1988-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* This utility is used to add credentials for a user to the NIS+ databases.
* Its syntax is as follows :
* nisaddcred [-p principal] [-P nis+_principal] [-l login_passwd] flavor
* nisaddcred -r [nis+_principal]
*/
/*
* The code is set up so that it may be possible to pass 'domain'
* as an optional argument. However, it is not clear whether it
* makes any sense to addcreds to other domains, and whether
* the code itself would work.
*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <sys/systeminfo.h>
#include <pwd.h>
#include <limits.h>
#include <rpcsvc/nis_dhext.h>
#define CRED_TABLE "cred.org_dir"
void
char *cmd;
{
"usage:\n\t%s [-p principal] [-P NIS+_principal] [-l login_password] ",
cmd);
"\t%s -r [NIS+_principal]\n", cmd);
exit(1);
}
extern int make_des_cred(), make_kerb_cred(),
extern char *get_des_cred(), *get_kerb_cred(),
static
struct {
char *name;
int (*makecred)();
char *(*pname)();
} known_flavors[] = {
#ifdef KERB_RSA_CREDS
#endif /* KERB_RSA_CREDS */
extern int optind;
extern char *optarg;
extern nis_name nis_local_host();
char *program_name = "nisaddcred";
nis_name my_nisname = 0;
char *my_host;
char *my_group;
int explicit_domain; /* if true, then a domain was specified on command line */
/*
* Similar to nis_local_principal (nis_subr.c) except
* this gets the results from the MASTER_ONLY and no FOLLOW_PATH.
* We only want the master because we'll be making updates there,
* and also the replicas may not have seen the 'nisaddacred local'
* that may have just occurred.
* Returns NULL if not found.
*/
char *
char *directory;
{
if (uid == 0)
return (nis_local_host());
"%s: unable to get result from NIS+ server.",
exit(1);
}
case NIS_SUCCESS:
/*
* More than one principal with same uid?
* something wrong with cred table. Should be unique
* Warn user and continue.
*/
"%s: LOCAL entry for %d in directory \"%s\" not unique",
}
return (principal_name);
case NIS_NOTFOUND:
return (NULL);
case NIS_TRYAGAIN :
"%s: NIS+ server busy, try again later.\n",
exit(1);
case NIS_PERMISSION :
"%s: insufficent permission to update credentials.\n",
exit(1);
default:
"%s: error talking to server, NIS+ error: %s.\n",
exit(1);
}
return (NULL);
}
/* Check whether this principal already has this type of credentials */
{
/* Don't want FOLLOW_PATH here */
switch (status) {
case NIS_NOTFOUND:
break;
case NIS_TRYAGAIN :
exit(1);
case NIS_PERMISSION :
"%s: insufficent permission to look at credentials table\n",
exit(1);
case NIS_SUCCESS:
case NIS_S_SUCCESS:
break;
default:
"%s: error looking at cred table, NIS+ error: %s\n",
exit(1);
}
return (status);
}
/* Check that someone else don't have the same auth information already */
{
char *foundprinc;
/* Don't want FOLLOW_PATH here */
case NIS_NOTFOUND:
break;
case NIS_TRYAGAIN :
"%s: NIS+ server busy, try again later.\n",
exit(1);
case NIS_PERMISSION :
"%s: insufficent permission to look up old credentials.\n",
exit(1);
case NIS_SUCCESS:
"%s: %s credentials with auth_name '%s' already belongs to '%s'.\n",
exit(1);
}
break;
default:
"%s: error looking at cred table, NIS+ error: %s\n",
exit(1);
}
return (status);
}
int
char *domain;
{
int status = 0;
case NIS_TRYAGAIN :
"%s: NIS+ server busy, try again later.\n",
exit(1);
case NIS_PERMISSION :
"%s: insufficent permission to update credentials.\n",
exit(1);
case NIS_SUCCESS :
status = 1;
break;
default:
"%s: error creating credential, NIS+ error: %s.\n",
exit(1);
}
return (status);
}
int
char *domain;
{
int status = 0;
/* Assume check for cred_exists performed already */
case NIS_TRYAGAIN :
"%s: NIS+ server busy, try again later.\n",
exit(1);
case NIS_PERMISSION :
"%s: insufficent permission to update credentials.\n",
exit(1);
case NIS_SUCCESS :
status = 1;
break;
default:
"%s: error creating credential, NIS+ error: %s.\n",
exit(1);
}
return (status);
}
void
unknown_flavor(char *flavor)
{
int i;
for (i = 0; known_flavors[i].name; i++)
else {
if (mechlist &&
!(AUTH_DES_COMPAT_CHK(mechlist[0]) &&
!mechlist[1])) {
int count;
else
}
} else
known_flavors[i].name);
}
exit(1);
}
void
char *flavor;
char *domain;
char *nisprinc;
char *princ;
{
int (*mc)();
char *(*gp)();
for (i = 0; i < fl; i++)
/* See if given flavor is one that we know */
break;
}
if (! mc) {
} else {
gp = get_des_cred;
}
gp = get_dhext_cred;
}
/*
* Call the function that will build the appropriate credential.
* When called, both the principal *and* the domain must be specified.
* some functions will complain if the domain and the domain of the
* principal (if fully qualified) differ.
*/
if (! princ) {
"%s: unable to determine your principal name for this flavor.\n",
exit(1);
}
}
if (! status) {
exit(1);
}
}
void
char *domain;
char *nis_princ;
{
exit(1);
}
/* Should do keylogout here if removing my own des credentials */
}
{
static nis_object obj;
return (&obj);
}
void
int argc;
char *argv[];
{
char *domain = nis_local_directory();
int len;
int c;
char *p;
program_name = argv[0];
nispasswd[0] = '\0';
if (argc == 1)
switch (c) {
case 'p' :
if (add_op == 0) {
"%s: cannot combine any other option with -r.\n",
}
break;
case 'P' :
if (add_op == 0) {
"%s: cannot combine any other option with -r.\n",
}
break;
case 'r':
(nispasswd[0] != '\0')) {
"%s: cannot combine any other option with -r.\n",
}
add_op = 0;
int ret;
if (ret == 0) {
fputs("\n\tThis machine appears to be a NIS+ server!!!\n",
stderr);
fputs("Are you sure you want to REMOVE it's credential?(Y/N) ",
stderr);
ansbuf[0] = '\0';
if (ansbuf[0] != 'y' &&
ansbuf[0] != 'Y') {
fputs("\nOkay not REMOVING this NIS+ server's credential\n",
stderr);
exit(1);
}
}
}
break;
case 'l':
if (add_op == 0) {
"%s: cannot combine any other option with -r.\n",
}
break;
case '?' :
default :
break;
}
}
if (add_op) {
"%s: Authentication Flavor name required.\n",
}
}
} else {
}
}
}
/* Information about user running nisaddcred */
my_host = nis_local_host();
my_group = nis_local_group();
/*
* Do a centralized check of nisprinc to make sure that
* it has a trailing ".", which is a common mistake that
* we can easily correct.
*/
if (nisprinc) {
if (p == NULL) {
"%s: out of memory\n", program_name);
exit(1);
}
strcat(p, ".");
nisprinc = p;
}
}
/*
* Do the same checking for domain, if it was specified on
* the command line.
*/
if (explicit_domain) {
if (p == NULL) {
"%s: out of memory\n", program_name);
exit(1);
}
strcat(p, ".");
domain = p;
}
}
if (add_op) {
} else
exit(0);
}
/*
* Get the password entry corresponding to 'uid' in the specified
* domain. If the domain is NULL and we can't get the information,
* then we get it locally (if USE_LOCAL_INFO is defined).
*/
struct passwd *
char *domain;
int uid;
{
struct passwd *getpwuid_nisplus_master();
#ifdef USE_LOCAL_INFO
/*
* If no domain was specified on the command line and we didn't
* get a password entry from NIS+, then try getting it locally.
*/
if (! explicit_domain && pw == 0)
#endif /* USE_LOCAL_INFO */
if (pw == 0) {
if (err == NIS_NOTFOUND)
"%s: no password entry found for uid %d\n",
program_name, uid);
else
"%s: could not get the password entry for uid %d: %s\n",
}
return (pw);
}
/*
* Get the shadow entry corresponding to 'name' in the specified
* domain. If the domain is NULL and we can't get the information,
* then we get it locally (if USE_LOCAL_INFO is defined).
*/
struct spwd *
char *domain;
char *name;
{
struct spwd *getspnam_nisplus_master();
#ifdef USE_LOCAL_INFO
/*
* If no domain was specified on the command line and we didn't
* get a shadow entry from NIS+, then try getting it locally.
*/
if (! explicit_domain && spw == 0)
#endif /* USE_LOCAL_INFO */
if (spw == 0) {
if (err == NIS_NOTFOUND)
"%s: no password entry found for user %s\n",
program_name, name);
else
"%s: could not get the password entry for user %s: %s\n",
}
return (spw);
}