makedhextcred.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 (c) 1997 Sun Microsystems Inc
* All Rights Reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* Make extended diffie-hellman GSS credential.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <pwd.h>
#include <shadow.h>
#include <nsswitch.h>
#include <netdb.h>
#include <rpcsvc/nis_dhext.h>
#include <rpc/key_prot.h>
#include "nisaddcred.h"
extern char *getpass();
extern char *crypt();
extern int add_cred_obj(nis_object *, char *);
extern nis_error auth_exists(char *, char *, char *, char *);
extern nis_error cred_exists(char *, char *, char *);
extern int keylogin_des(char *, char *);
extern int make_des_cred_be(char *, char *, char *);
extern int modify_cred_obj(nis_object *, char *);
static const char *OPSYS = "unix";
#define OPSYS_LEN 4
#define ROOTKEY_FILE "/etc/.rootkey"
/* ************************ switch functions *************************** */
/* NSW_NOTSUCCESS NSW_NOTFOUND NSW_UNAVAIL NSW_TRYAGAIN */
static struct __nsw_switchconfig publickey_default =
char *
{
struct __nsw_lookup *look;
static char policy[256];
int previous = 0;
if (previous)
previous = 1;
}
return (policy);
}
int
{
}
int
{
}
int
struct __nsw_switchconfig *default_conf,
{
struct __nsw_switchconfig *conf;
enum __nsw_parse_err perr;
int policy_correct = 1;
if (no_switch_policy(conf)) {
"\n%s\n There is no publickey entry in %s.\n",
" The default publickey policy is \"publickey: %s\".\n",
policy_correct = 0;
}
"\n%s\n The publickey entry in %s is \"publickey: %s\".\n",
policy_correct = 0;
}
/* should we exit ? */
if (policy_correct == 0)
" It should be \"publickey: %s\"%s.\n\n",
if (conf)
return (policy_correct);
}
/* ******************************************************************** */
/* Check that data to be entered makes sense */
int
{
char *princdomain, *netdomain;
/* Sanity check 0. Do we have a nis+ principal name to work with? */
"%s: you must create a \"local\" credential first.\n",
"rerun this command as : %s local \n", program_name);
return (0);
}
/* Sanity check 1. We only deal with one type of netnames. */
return (0);
}
/* Sanity check 2. Should only add DES cred in home domain. */
"%s: domain of principal '%s' does not match destination domain '%s'.\n",
"Should only add DES credential of principal in its home domain\n");
return (0);
}
/*
* Sanity check 3: Make sure netname's domain same as principal's
* and don't have extraneous dot at the end.
*/
if (! netdomain) {
return (0);
}
netdomain++; /* skip '@' */
"be same as that of principal \"%s\"\n",
return (0);
}
/* Check publickey policy and warn user if it is not NIS+ */
"WARNING:", " when using NIS+");
/* Another principal owns same credentials? (exits if that happens) */
return (1); /* all passed */
}
/* ***************************** keylogin stuff *************************** */
static int
{
mechanism_t **mechs;
int mcount;
NULL, 0,
< 0) {
"Could not set %s's %s secret key\n",
"May be the keyserv is down?\n");
return (0);
}
}
}
} else {
}
return (1);
}
/*
* fgets is broken in that if it reads a NUL character it will always return
* EOF. This replacement can deal with NULs
*/
static char *
{
int i = 0;
int rs = 0;
char c;
if (fildes < 0)
return (NULL);
while (i < n - 1) {
switch (rs) {
case 1:
break;
case 0:
/* EOF */
if (i > 0)
s[i] = '\0';
return (NULL);
break;
default:
return (NULL);
}
switch (c) {
case '\0':
break;
case '\n':
s[i] = c;
s[++i] = '\0';
return (s);
default:
if (c != '\0')
s[i++] = c;
}
}
s[i] = '\0';
return (s);
}
#define ROOTKEY_FILE_BACKUP "/etc/.rootkey.bak"
/* Should last until 16384-bit DH keys */
#define MAXROOTKEY_LINE_LEN 4224
#define MAXROOTKEY_LEN 4096
/* write unencrypted secret key into root key file */
void
{
char line[MAXROOTKEY_LINE_LEN];
char keyent[MAXROOTKEY_LEN];
perror("Could not create /etc/.rootkey.bak");
goto rootkey_err;
}
}
perror("Could not open /etc/.rootkey for writing");
"Attempting to restore original /etc/.rootkey\n");
goto rootkey_err;
}
perror("Could not open /etc/.rootkey for writing");
"Attempting to restore original /etc/.rootkey\n");
goto rootkey_err;
}
perror("Could not open /etc/.rootkey.bak for reading");
"Attempting to restore original /etc/.rootkey\n");
goto rootkey_err;
}
/*
* 192-bit keys always go on the first line
*/
if (lineone) {
if (keylen == 192) {
} else
} else {
/*
* Silently remove lines with the same
*/
if (gotit)
continue;
else
} else
}
}
/* Append key to rootkey file */
if (!gotit) {
if (keylen == 192)
else {
if (lineone)
}
}
return;
flavor);
}
char *
{
static char password[256];
char prompt[256];
int passwords_matched = 0;
struct passwd *domain_getpwuid();
struct spwd *domain_getspnam();
/* ignore password checking when the -l option is used */
if (nispasswd[0] != '\0')
return (nispasswd);
if (uid == 0) {
if (same_host) {
/*
* The root user is never in the NIS+
* data base. Get it locally.
*/
if (! pw) {
"%s: unable to locate password record for uid %d\n",
program_name, uid);
return (0);
}
if (!spw) {
"%s: unable to locate password record for uid 0\n",
return (0);
}
}
} else {
if (pw) {
/* get password from shadow */
if (spw) {
}
} else {
return (0);
}
}
else if (uid == 0) {
} else
return (0);
}
/* Verify that password supplied matches login password */
passwords_matched = 1;
else {
"%s: %s: password differs from login password.\n",
if (!force)
return (0);
}
}
/* Check for mis-typed password */
if (!passwords_matched) {
return (0);
}
}
return (password);
}
/*
* Definitions of the credential table.
*
* Column Name Contents
* ------ ---- --------
* 0 cname nis principal name
* 1 auth_type DES
* 2 auth_name netname
* 3 public_auth_data public key
* 4 private_auth_data encrypted secret key with checksum
*/
/*
* Function for building DES credentials.
*
* The domain may be the local domain or some remote domain.
* 'domain' should be the same as the domain found in netname,
* which should be the home domain of nis+ principal.
*/
int
char *nis_princ; /* NIS+ principal name */
char *netname; /* AUTH_DES netname */
char *domain; /* Domain name */
char *flavor; /* Mech alias */
{
static char *pass;
char authtype[MECH_MAXATNAME];
int same_host = 0;
goto badstatus;
goto badstatus;
uid = 0; /* root */
same_host = 1;
} else {
}
if (!pass)
if (!pass)
goto badstatus;
/* Get password with which to encrypt secret key. */
(void) printf("%s %s key pair for %s (%s).\n",
goto badstatus;
goto badstatus;
/* Encrypt secret key */
goto badstatus;
goto badstatus;
/* Now we have a key pair, build up the cred entry */
if (addition) {
/* owner: r, group: rmcd */
NIS_DESTROY_ACC)<<8);
} else {
}
/* attempt keylogin if appropriate */
if (status) {
}
goto cleanup;
status = 0;
return (status);
}
char *
{
if (uid == 0)
else {
/* generate netname using uid and domain information. */
int len;
goto not_found;
}
status = 1;
}
if (status == 1) {
return (netname);
}
return (NULL);
}