summaryrefslogtreecommitdiff
path: root/usr/src/lib/passwdutil
diff options
context:
space:
mode:
authorRaja Andra <Rajagopal.Andra@Sun.COM>2009-12-06 01:39:21 -0800
committerRaja Andra <Rajagopal.Andra@Sun.COM>2009-12-06 01:39:21 -0800
commit36e852a172cba914383d7341c988128b2c667fbd (patch)
tree6cf9fe61b54ffa5f49f74f8b3ee20249279d5efe /usr/src/lib/passwdutil
parent560e0ee2bb5791b5efe2cbdc74d0a76f06dbd84d (diff)
downloadillumos-joyent-36e852a172cba914383d7341c988128b2c667fbd.tar.gz
6874309 Remove NIS+ from Solaris
Diffstat (limited to 'usr/src/lib/passwdutil')
-rw-r--r--usr/src/lib/passwdutil/Makefile.com23
-rw-r--r--usr/src/lib/passwdutil/__failed_count.c4
-rw-r--r--usr/src/lib/passwdutil/__set_authtoken_attr.c16
-rw-r--r--usr/src/lib/passwdutil/__verify_rpc_passwd.c68
-rw-r--r--usr/src/lib/passwdutil/files_attr.c11
-rw-r--r--usr/src/lib/passwdutil/ldap_attr.c10
-rw-r--r--usr/src/lib/passwdutil/mapfile-vers1
-rw-r--r--usr/src/lib/passwdutil/nis_attr.c40
-rw-r--r--usr/src/lib/passwdutil/nisplus_attr.c1483
-rw-r--r--usr/src/lib/passwdutil/npd_clnt.c567
-rw-r--r--usr/src/lib/passwdutil/npd_clnt.h51
-rw-r--r--usr/src/lib/passwdutil/nss_attr.c6
-rw-r--r--usr/src/lib/passwdutil/passwdutil.h53
-rw-r--r--usr/src/lib/passwdutil/switch_utils.c329
-rw-r--r--usr/src/lib/passwdutil/utils.c11
15 files changed, 58 insertions, 2615 deletions
diff --git a/usr/src/lib/passwdutil/Makefile.com b/usr/src/lib/passwdutil/Makefile.com
index 7e186652c9..e1064ca799 100644
--- a/usr/src/lib/passwdutil/Makefile.com
+++ b/usr/src/lib/passwdutil/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -29,21 +29,16 @@ OBJ= __check_history.o \
__set_authtoken_attr.o \
__get_authtoken_attr.o \
__user_to_authenticate.o \
- __verify_rpc_passwd.o \
__failed_count.o \
files_attr.o \
nis_attr.o \
- npd_clnt.o \
- nisplus_attr.o \
ldap_attr.o \
nss_attr.o \
switch_utils.o \
utils.o \
debug.o
-DERIVED_OBJ= nispasswd_xdr.o
-
-OBJECTS= $(OBJ) $(DERIVED_OBJ)
+OBJECTS= $(OBJ)
include ../../Makefile.lib
@@ -61,26 +56,12 @@ CPPFLAGS += -DENABLE_SUNOS_AGING -D_REENTRANT \
-I$(SRC)/lib/libsldap/common -I$(SRC)/lib/libnsl/include
CFLAGS += $(CCVERBOSE)
-#
-# We depend upon a rpcgen file. Specify some additional macros
-# to correctly build and get rid of the derived file
-#
-PROTOCOL_DIR= ../../../head/rpcsvc
-DERIVED_FILES= ../nispasswd_xdr.c
-CLOBBERFILES += $(DERIVED_FILES)
-
-#
-# Don't lint derived files
-#
lint := SRCS= $(OBJ:%.o=$(SRCDIR)/%.c)
.KEEP_STATE:
all: $(LIBS)
-../nispasswd_xdr.c: $(PROTOCOL_DIR)/nispasswd.x
- $(RPCGEN) -c -C -M $(PROTOCOL_DIR)/nispasswd.x > ../nispasswd_xdr.c
-
lint: lintcheck
include ../../Makefile.targ
diff --git a/usr/src/lib/passwdutil/__failed_count.c b/usr/src/lib/passwdutil/__failed_count.c
index a72a2fba26..6d5b19992a 100644
--- a/usr/src/lib/passwdutil/__failed_count.c
+++ b/usr/src/lib/passwdutil/__failed_count.c
@@ -69,7 +69,7 @@ __incr_failed_count(char *username, char *repname, int max_failures)
if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS)
goto out;
}
- if (((ret = ops->putpwnam(username, NULL, NULL, NULL, buf)) ==
+ if (((ret = ops->putpwnam(username, NULL, NULL, buf)) ==
PWU_SUCCESS) &&
(items[0].type == ATTR_LOCK_ACCOUNT))
ret = PWU_ACCOUNT_LOCKED;
@@ -113,7 +113,7 @@ __rst_failed_count(char *username, char *repname)
goto out;
if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS)
goto out;
- ret = ops->putpwnam(username, NULL, NULL, NULL, buf);
+ ret = ops->putpwnam(username, NULL, NULL, buf);
out:
if (ops->unlock != NULL) {
ops->unlock();
diff --git a/usr/src/lib/passwdutil/__set_authtoken_attr.c b/usr/src/lib/passwdutil/__set_authtoken_attr.c
index 6b4f43eb88..d54cbc65a9 100644
--- a/usr/src/lib/passwdutil/__set_authtoken_attr.c
+++ b/usr/src/lib/passwdutil/__set_authtoken_attr.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <errno.h>
#include <sys/types.h>
#include <sys/types.h>
@@ -38,8 +35,8 @@
#include "passwdutil.h"
int
-__set_authtoken_attr(char *name, char *oldpw, char *oldrpcpw,
- pwu_repository_t *rep, attrlist *items, int *updated_reps)
+__set_authtoken_attr(char *name, char *oldpw, pwu_repository_t *rep,
+ attrlist *items, int *updated_reps)
{
attrlist *p;
int repositories;
@@ -93,8 +90,7 @@ __set_authtoken_attr(char *name, char *oldpw, char *oldrpcpw,
err = rops[i]->update(items, rep, buf);
if ((err == PWU_SUCCESS) && rops[i]->putpwnam)
- err = rops[i]->putpwnam(name, oldpw, oldrpcpw,
- rep, buf);
+ err = rops[i]->putpwnam(name, oldpw, rep, buf);
if (rops[i]->unlock)
(void) rops[i]->unlock();
diff --git a/usr/src/lib/passwdutil/__verify_rpc_passwd.c b/usr/src/lib/passwdutil/__verify_rpc_passwd.c
deleted file mode 100644
index e0bfd6ca2f..0000000000
--- a/usr/src/lib/passwdutil/__verify_rpc_passwd.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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
- * or http://www.opensolaris.org/os/licensing.
- * 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 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "passwdutil.h"
-
-extern int nisplus_verify_rpc_passwd(char *name, char *oldpw,
- pwu_repository_t *rep);
-
-int
-__verify_rpc_passwd(char *name, char *oldpw, pwu_repository_t *rep)
-{
- int repositories;
- int pwu_res;
-
- repositories = get_ns(rep, PWU_READ);
-
- if (repositories == 0)
- return (PWU_SYSTEM_ERROR);
-
- if (repositories == REP_ERANGE)
- return (PWU_REPOSITORY_ERROR);
-
- /*
- * If NIS+ is not used, then there is no need for an old RPC
- * password.
- */
- if ((repositories & REP_NISPLUS) == 0)
- return (PWU_SUCCESS);
-
- pwu_res = nisplus_verify_rpc_passwd(name, oldpw, rep);
-
- /*
- * If the user can't be found in NIS+ _and_ there are other
- * repositories defined, not being able to find the user in NIS+
- * is not necessarily fatal, so return SUCCESS here.
- * If it turns out NIS+ the user can't be found in the other
- * repositories, we'll bail out later on.
- */
- if ((pwu_res == PWU_NOT_FOUND) && (repositories & ~REP_NISPLUS) != 0)
- pwu_res = PWU_SUCCESS;
-
- return (pwu_res);
-}
diff --git a/usr/src/lib/passwdutil/files_attr.c b/usr/src/lib/passwdutil/files_attr.c
index b7d128cd20..2a8ac5c94f 100644
--- a/usr/src/lib/passwdutil/files_attr.c
+++ b/usr/src/lib/passwdutil/files_attr.c
@@ -49,8 +49,7 @@ int files_getattr(char *name, attrlist *item, pwu_repository_t *rep);
int files_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
void **buf);
int files_update(attrlist *items, pwu_repository_t *rep, void *buf);
-int files_putpwnam(char *name, char *oldpw, char *dummy,
- pwu_repository_t *rep, void *buf);
+int files_putpwnam(char *name, char *oldpw, pwu_repository_t *rep, void *buf);
int files_user_to_authenticate(char *name, pwu_repository_t *rep,
char **auth_user, int *privileged);
@@ -1086,16 +1085,14 @@ passwd_exit:
}
/*
- * files_putpwnam(name, oldpw, dummy, rep, buf)
+ * files_putpwnam(name, oldpw, rep, buf)
*
* store the password attributes contained in "buf" in /etc/passwd and
- * /etc/shadow. The dummy parameter is a placeholder for NIS+
- * updates where the "oldrpc" password is passed.
+ * /etc/shadow.
*/
/*ARGSUSED*/
int
-files_putpwnam(char *name, char *oldpw, char *dummy,
- pwu_repository_t *rep, void *buf)
+files_putpwnam(char *name, char *oldpw, pwu_repository_t *rep, void *buf)
{
struct pwbuf *pwbuf = (struct pwbuf *)buf;
int result = PWU_SUCCESS;
diff --git a/usr/src/lib/passwdutil/ldap_attr.c b/usr/src/lib/passwdutil/ldap_attr.c
index c0bb113ec0..43d6b7dd19 100644
--- a/usr/src/lib/passwdutil/ldap_attr.c
+++ b/usr/src/lib/passwdutil/ldap_attr.c
@@ -74,8 +74,7 @@ int ldap_getattr(char *name, attrlist *item, pwu_repository_t *rep);
int ldap_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
void **buf);
int ldap_update(attrlist *items, pwu_repository_t *rep, void *buf);
-int ldap_putpwnam(char *name, char *oldpw, char *dummy,
- pwu_repository_t *rep, void *buf);
+int ldap_putpwnam(char *name, char *oldpw, pwu_repository_t *rep, void *buf);
int ldap_user_to_authenticate(char *name, pwu_repository_t *rep,
char **auth_user, int *privileged);
@@ -1130,16 +1129,13 @@ out:
/*
- * ldap_putpwnam(name, oldpw, dummy, rep, buf)
+ * ldap_putpwnam(name, oldpw, rep, buf)
*
* update the LDAP server with the attributes contained in 'buf'.
- * The dummy parameter is a placeholder for NIS+ where the old
- * RPC password is passwd.
*/
/*ARGSUSED*/
int
-ldap_putpwnam(char *name, char *oldpw, char *dummy,
- pwu_repository_t *rep, void *buf)
+ldap_putpwnam(char *name, char *oldpw, pwu_repository_t *rep, void *buf)
{
int res;
char *dn; /* dn of user whose attributes we are changing */
diff --git a/usr/src/lib/passwdutil/mapfile-vers b/usr/src/lib/passwdutil/mapfile-vers
index 1c2eaa3cd6..d6cfe0ad89 100644
--- a/usr/src/lib/passwdutil/mapfile-vers
+++ b/usr/src/lib/passwdutil/mapfile-vers
@@ -45,7 +45,6 @@ SUNWprivate_1.1 {
__rst_failed_count;
__set_authtoken_attr;
__user_to_authenticate;
- __verify_rpc_passwd;
local:
*;
};
diff --git a/usr/src/lib/passwdutil/nis_attr.c b/usr/src/lib/passwdutil/nis_attr.c
index c05dc9a7da..b996d585bb 100644
--- a/usr/src/lib/passwdutil/nis_attr.c
+++ b/usr/src/lib/passwdutil/nis_attr.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
@@ -48,8 +45,7 @@ int nis_getattr(char *name, attrlist *item, pwu_repository_t *rep);
int nis_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
void **buf);
int nis_update(attrlist *items, pwu_repository_t *rep, void *buf);
-int nis_putpwnam(char *name, char *oldpw, char *dummy,
- pwu_repository_t *rep, void *buf);
+int nis_putpwnam(char *name, char *oldpw, pwu_repository_t *rep, void *buf);
int nis_user_to_authenticate(char *user, pwu_repository_t *rep,
char **auth_user, int *privileged);
@@ -317,7 +313,7 @@ nis_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
if (yp_master(nisbuf->domain, "passwd.byname", &nisbuf->master) != 0) {
syslog(LOG_ERR,
- "passwdutil.so: can't get master for passwd map");
+ "passwdutil.so: can't get master for passwd map");
if (nisbuf->master)
free(nisbuf->master);
free(nisbuf->pwd);
@@ -326,8 +322,8 @@ nis_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
}
nisresult = yp_match(nisbuf->domain, "passwd.byname", name,
- strlen(name), &(nisbuf->scratch),
- &(nisbuf->scratchlen));
+ strlen(name), &(nisbuf->scratch),
+ &(nisbuf->scratchlen));
if (nisresult != 0) {
(void) free(nisbuf->pwd);
if (nisbuf->scratch)
@@ -357,8 +353,8 @@ nis_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
keylen = strlen(key);
nisresult = yp_match(nisbuf->domain, "passwd.adjunct.byname",
- key, keylen, &(nisbuf->c2scratch),
- &(nisbuf->c2scratchlen));
+ key, keylen, &(nisbuf->c2scratch),
+ &(nisbuf->c2scratchlen));
if (nisresult == 0 && nisbuf->c2scratch != NULL) {
/* Skip username (first field), and pick up password */
@@ -450,16 +446,14 @@ nis_update(attrlist *items, pwu_repository_t *rep, void *buf)
}
/*
- * nis_putpwnam(name, oldpw, dummy, rep, buf)
+ * nis_putpwnam(name, oldpw, rep, buf)
*
* Update the NIS server. The passwd structure in buf will be sent to
* the server for user "name" authenticating with password "oldpw".
- * The dummy parameter is a placeholder where for NIS+ where the
- * old RPC password is passwd.
*/
/*ARGSUSED*/
int
-nis_putpwnam(char *name, char *oldpw, char *dummy, pwu_repository_t *rep,
+nis_putpwnam(char *name, char *oldpw, pwu_repository_t *rep,
void *buf)
{
nisbuf_t *nisbuf = (nisbuf_t *)buf;
@@ -484,24 +478,24 @@ nis_putpwnam(char *name, char *oldpw, char *dummy, pwu_repository_t *rep,
nconf = getnetconfigent("ticlts");
if (!nconf) {
syslog(LOG_ERR,
- "passwdutil.so: Couldn't get netconfig entry");
+ "passwdutil.so: Couldn't get netconfig entry");
return (PWU_SYSTEM_ERROR);
}
client = clnt_tp_create(nisbuf->master, YPPASSWDPROG,
- YPPASSWDVERS, nconf);
+ YPPASSWDVERS, nconf);
freenetconfigent(nconf);
} else {
/* Try IPv6 first */
client = clnt_create(nisbuf->master, YPPASSWDPROG,
- YPPASSWDVERS, "udp6");
+ YPPASSWDVERS, "udp6");
if (client == NULL)
client = clnt_create(nisbuf->master, YPPASSWDPROG,
- YPPASSWDVERS, "udp");
+ YPPASSWDVERS, "udp");
}
if (client == NULL) {
syslog(LOG_ERR,
- "passwdutil.so: couldn't create client to YP master");
+ "passwdutil.so: couldn't create client to YP master");
return (PWU_SERVER_ERROR);
}
@@ -509,7 +503,7 @@ nis_putpwnam(char *name, char *oldpw, char *dummy, pwu_repository_t *rep,
timeout.tv_sec = 55; /* ndp uses 55 seconds */
ans = CLNT_CALL(client, YPPASSWDPROC_UPDATE, xdr_yppasswd,
- (char *)&yppasswd, xdr_int, (char *)&ok, timeout);
+ (char *)&yppasswd, xdr_int, (char *)&ok, timeout);
if (nisbuf->pwd)
(void) free(nisbuf->pwd);
diff --git a/usr/src/lib/passwdutil/nisplus_attr.c b/usr/src/lib/passwdutil/nisplus_attr.c
deleted file mode 100644
index 72f3de7b19..0000000000
--- a/usr/src/lib/passwdutil/nisplus_attr.c
+++ /dev/null
@@ -1,1483 +0,0 @@
-/*
- * 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
- * or http://www.opensolaris.org/os/licensing.
- * 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 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <shadow.h>
-#include <syslog.h>
-#include <rpc/types.h>
-#include <rpc/key_prot.h>
-#include <rpcsvc/nis.h>
-#include <rpcsvc/nispasswd.h>
-#include <limits.h>
-#include <nss_dbdefs.h>
-
-#include <rpcsvc/nis_dhext.h>
-
-#include "passwdutil.h"
-#include "utils.h"
-#include "npd_clnt.h"
-
-/*
- * nis+ definition
- */
-#define PKTABLE "cred.org_dir"
-#define PKTABLELEN 12
-#define PASSTABLE "passwd.org_dir"
-#define PASSTABLELEN 14
-#define PKMAP "publickey.byname"
-
-/*
- * NIS+ columns
- */
-#define COL_NAME 0
-#define COL_PASSWD 1
-#define COL_UID 2
-#define COL_GID 3
-#define COL_GECOS 4
-#define COL_HOMEDIR 5
-#define COL_SHELL 6
-#define COL_SHADOW 7
-
-/*
- * undocumented NIS+ interface
- */
-extern bool_t __nis_isadmin(char *, char *, char *);
-
-
-int nisplus_getattr(char *name, attrlist *item, pwu_repository_t *rep);
-int nisplus_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
- void **buf);
-int nisplus_update(attrlist *items, pwu_repository_t *rep, void *buf);
-int nisplus_putpwnam(char *name, char *oldpw, char *oldrpcpw,
- pwu_repository_t *rep, void *buf);
-int nisplus_user_to_authenticate(char *user, pwu_repository_t *rep,
- char **auth_user, int *privileged);
-
-/*
- * nisplus function pointer table, used by passwdutil_init to initialize
- * the global Repository-OPerations table "rops"
- */
-struct repops nisplus_repops = {
- NULL, /* checkhistory */
- nisplus_getattr,
- nisplus_getpwnam,
- nisplus_update,
- nisplus_putpwnam,
- nisplus_user_to_authenticate,
- NULL, /* lock */
- NULL /* unlock */
-};
-
-#define PWU_NO_PROTO 0
-#define PWU_OLD_PROTO 1
-#define PWU_NEW_PROTO 2
-
-/*
- * This structure is used to keep state between get/update/put calls
- */
-struct statebuf {
- struct passwd *pwd;
- struct spwd *spwd;
- char *domain;
- int proto; /* which protocol to use for the update */
- int col_flags[8]; /* keep track of which NIS+ columns changed */
- int hash_pword; /* password is plaintext, hash before storing */
-};
-
-/*
- * These messages match the nispasswd_code values in <rpcsvc/nispasswd.h>
- */
-char *npd_errmsg[] = {
- "Password update daemon is not running with NIS+ master server",
- "User has no NIS+ password entry",
- "NIS+ identifier invalid",
- "User has no NIS+ password entry",
- "No shadow password information",
- "Shadow information corrupt",
- "NIS+ password has not aged enough",
- "Couldn't generate a common DES key",
- "Invalid verifier",
- "NIS+ password invalid",
- "NIS+ server failed to encrypt verifier",
- "NIS+ server failed to decrypt password",
- "NIS+ keys updated",
- "NIS+ server could not re-encrypt key",
- "Permission denied",
- "NIS+ server not responding",
- "NIS+ error",
- "NIS+ system error",
- "NIS+ buffer too small",
- "Invalid arguments"
-};
-
-int nisplus_get_cred(uid_t uid, char *domain, nis_result **cred_res);
-int extract_sec_keyinfo(nis_object *cred_entry, char **seckey,
- char **authtype, keylen_t *keylen, algtype_t *algtype);
-
-char *reencrypt_secret(char *oldsec, char *oldpass, char *newpass,
- uid_t uid, keylen_t keylen, algtype_t algtype);
-int nisplus_old_proto(char *name, char *oldpw, char *oldrpcpw,
- pwu_repository_t *rep, void *buf);
-
-/*
- * nisplus_handle(name, domain, access_type)
- *
- * Create a handle used to talk to the NIS+ server
- *
- * 'access_type' flag is used to check whether we are doing a lookup or
- * an update. If it's update, we will use MASTER_ONLY flag in the
- * call to nis_list(). If it's lookup, it's okay to go and search
- * in replica's database when master is down.
- *
- */
-nis_result *
-nisplus_handle(char *name, char *domain, int access_type)
-{
- char buf[NIS_MAXNAMELEN+1];
- nis_result *handle;
-
- if ((strlen(name) + strlen(domain) + PASSTABLELEN + 9) >
- (size_t)NIS_MAXNAMELEN)
- return (NULL);
-
- (void) snprintf(buf, sizeof (buf), "[name=%s],%s.%s", name, PASSTABLE,
- domain);
- if (buf[strlen(buf) - 1] != '.')
- (void) strcat(buf, ".");
-
- if (access_type == NISPLUS_LOOKUP)
- handle = nis_list(buf,
- USE_DGRAM+FOLLOW_LINKS+FOLLOW_PATH, NULL, NULL);
- else
- handle = nis_list(buf,
- USE_DGRAM+FOLLOW_LINKS+FOLLOW_PATH+MASTER_ONLY, NULL, NULL);
-
- if (handle->status != NIS_SUCCESS)
- return (NULL);
-
- return (handle);
-}
-
-/*
- * determine the name of the domain this user's account resides in.
- */
-nis_name
-get_pwd_domain(char *user, char *domain)
-{
- nis_result *handle;
- nis_name pwd_domain;
-
- handle = nisplus_handle(user, domain, NISPLUS_LOOKUP);
- if (handle == NULL)
- return (nis_local_directory());
-
- pwd_domain = NIS_RES_OBJECT(handle)->zo_domain;
-
- if (strcmp(nis_leaf_of(pwd_domain), "org_dir") == 0)
- pwd_domain = nis_domain_of(pwd_domain);
-
- return (pwd_domain);
-}
-
-int
-nisplus_privileged(char *user, char *domain)
-{
- nis_name local_principal;
- uid_t old_euid;
-
- /*
- * In contrast to what we'd like, we really need to set the effective
- * UID here, in order for nis_local_principal() to return an answer
- * based on *who* we are instead of *what privileges* we have.
- *
- * This makes this module thread-unsafe!
- */
- old_euid = seteuid(getuid());
- local_principal = nis_local_principal();
- (void) seteuid(old_euid);
-
- return (__nis_isadmin(local_principal, "passwd",
- get_pwd_domain(user, domain)));
-}
-
-
-/*
- * nisplus_user_to_authenticate(user, rep, auth_user, privileged)
- */
-int
-nisplus_user_to_authenticate(char *user, pwu_repository_t *rep,
- char **auth_user, int *privileged)
-{
- int res;
- struct statebuf *buf = NULL;
-
- /*
- * special case: don't bother to get root from NIS+
- */
- if (strcmp(user, "root") == 0)
- return (PWU_NOT_FOUND);
-
- res = nisplus_getpwnam(user, NULL, rep, (void **)&buf);
- if (res != PWU_SUCCESS)
- return (res);
-
- res = PWU_SUCCESS;
-
- if (nisplus_privileged(user, buf->domain) == 0) {
- *privileged = 0;
- if ((*auth_user = strdup(user)) == NULL)
- res = PWU_NOMEM;
- goto out;
- } else {
- uid_t uid = getuid();
- char pwd_buf[NSS_BUFLEN_PASSWD];
- struct passwd pwr;
-
- *privileged = 1;
-
- if (getpwuid_r(uid, &pwr, pwd_buf, sizeof (pwd_buf)) == NULL) {
-#define MAX_UID_LEN 11 /* UID's larger than 2^32 won't fit */
- if ((*auth_user = malloc(MAX_UID_LEN)) == NULL) {
- res = PWU_NOMEM;
- goto out;
- }
- (void) snprintf(*auth_user, MAX_UID_LEN, "%d",
- (int)uid);
- } else {
- if ((*auth_user = strdup(pwr.pw_name)) == NULL)
- res = PWU_NOMEM;
- }
- }
-
-out:
- if (buf->pwd)
- free_pwd(buf->pwd);
- if (buf->spwd)
- free_spwd(buf->spwd);
- if (buf)
- free(buf);
-
- return (res);
-}
-
-/*
- * nisplus_getattr(name, items, rep)
- *
- * retrieve attributes specified in "items"
- */
-int
-nisplus_getattr(char *name, attrlist *items, pwu_repository_t *rep)
-{
- attrlist *p;
- int res;
- struct statebuf *buf = NULL;
-
- res = nisplus_getpwnam(name, items, rep, (void **)&buf);
- if (res != PWU_SUCCESS)
- return (res);
-
- for (p = items; res == PWU_SUCCESS && p != NULL; p = p->next) {
- switch (p->type) {
- case ATTR_NAME:
- if ((p->data.val_s = strdup(buf->pwd->pw_name)) == NULL)
- res = PWU_NOMEM;
- break;
- case ATTR_GECOS:
- p->data.val_s = strdup(buf->pwd->pw_gecos);
- if (p->data.val_s == NULL)
- res = PWU_NOMEM;
- break;
- case ATTR_HOMEDIR:
- if ((p->data.val_s = strdup(buf->pwd->pw_dir)) == NULL)
- res = PWU_NOMEM;
- break;
- case ATTR_SHELL:
- p->data.val_s = strdup(buf->pwd->pw_shell);
- if (p->data.val_s == NULL)
- res = PWU_NOMEM;
- break;
- case ATTR_PASSWD:
- case ATTR_PASSWD_SERVER_POLICY:
- p->data.val_s = strdup(buf->spwd->sp_pwdp);
- if (p->data.val_s == NULL)
- res = PWU_NOMEM;
- break;
- case ATTR_REP_NAME:
- if ((p->data.val_s = strdup("nisplus")) == NULL)
- res = PWU_NOMEM;
- break;
-
- case ATTR_UID:
- p->data.val_i = buf->pwd->pw_uid;
- break;
- case ATTR_GID:
- p->data.val_i = buf->pwd->pw_gid;
- break;
- case ATTR_LSTCHG:
- p->data.val_i = buf->spwd->sp_lstchg;
- break;
- case ATTR_MIN:
- p->data.val_i = buf->spwd->sp_min;
- break;
- case ATTR_MAX:
- p->data.val_i = buf->spwd->sp_max;
- break;
- case ATTR_WARN:
- p->data.val_i = buf->spwd->sp_warn;
- break;
- case ATTR_INACT:
- p->data.val_i = buf->spwd->sp_inact;
- break;
- case ATTR_EXPIRE:
- p->data.val_i = buf->spwd->sp_expire;
- break;
- case ATTR_FLAG:
- p->data.val_i = buf->spwd->sp_flag;
- break;
- default:
- break;
- }
- }
-
-out:
- if (buf->pwd)
- free_pwd(buf->pwd);
- if (buf->spwd)
- free_spwd(buf->spwd);
- if (buf)
- free(buf);
-
- return (res);
-}
-
-/*
- * nisplus_getpwnam(name, items, rep, buf)
- *
- * Get all account info on user "name".
- */
-/*ARGSUSED*/
-int
-nisplus_getpwnam(char *name, attrlist *items, pwu_repository_t *rep,
- void **buf)
-{
- struct statebuf *statebuf;
- int res;
-
- statebuf = (struct statebuf *)calloc(1, sizeof (struct statebuf));
- if (statebuf == NULL)
- return (PWU_NOMEM);
-
- res = dup_pw(&statebuf->pwd, getpwnam_from(name, rep, REP_NISPLUS));
- if (res != PWU_SUCCESS) {
- if (statebuf->pwd)
- free_pwd(statebuf->pwd);
- free(statebuf);
- return (res);
- }
-
- res = dup_spw(&statebuf->spwd, getspnam_from(name, rep, REP_NISPLUS));
- if (res != PWU_SUCCESS) {
- if (statebuf->pwd)
- free_pwd(statebuf->pwd);
- if (statebuf->spwd)
- free_spwd(statebuf->spwd);
- free(statebuf);
- return (res);
- }
-
- *buf = (void *)statebuf;
-
- if (rep && rep->scope)
- statebuf->domain = strdup(rep->scope);
- else
- statebuf->domain =
- strdup(get_pwd_domain(name, nis_local_directory()));
-
- /*
- * The protocol to use will be determined in nisplus_update()
- */
- statebuf->proto = PWU_NO_PROTO;
- statebuf->hash_pword = 0;
-
- return (PWU_SUCCESS);
-}
-
-/*
- * max_present(list)
- *
- * returns '1' if a ATTR_MAX with value != -1 is present. (in other words:
- * if password aging is to be turned on).
- */
-static int
-max_present(attrlist *list)
-{
- while (list != NULL)
- if (list->type == ATTR_MAX && list->data.val_i != -1)
- return (1);
- else
- list = list->next;
- return (0);
-}
-
-/*
- * nisplus_update(items, rep, buf)
- *
- * Update the information in "buf" to reflect the attributes specified
- * in items
- */
-/*ARGSUSED*/
-int
-nisplus_update(attrlist *items, pwu_repository_t *rep, void *buf)
-{
- attrlist *p;
- struct statebuf *statebuf;
- struct passwd *pw;
- struct spwd *spw;
- char *pword;
- int len;
- char newpw[_PASS_MAX+1];
-
- statebuf = (struct statebuf *)buf;
- pw = statebuf->pwd;
- spw = statebuf->spwd;
-
- /*
- * There are two different protocols that can be used to
- * update the NIS+ server. The "new" protocol can be used
- * for "passwd", "gecos" and "shell" info. All other info
- * needs to be changed using the "old" protocol.
- *
- * Since nisplus_putpwnam() does not know what attributes
- * have been changed, we keep track of which protocol to use
- * in here.
- */
-
- for (p = items; p != NULL; p = p->next) {
- switch (p->type) {
- /*
- * We don't update NAME, UID, GID
- */
- case ATTR_NAME:
- case ATTR_UID:
- case ATTR_GID:
- break;
- /*
- * AGE and COMMENT are not supported by NIS+
- */
- case ATTR_AGE:
- case ATTR_COMMENT:
- break;
-
- /*
- * Nothing special needs to be done for
- * server policy
- */
- case ATTR_PASSWD:
- case ATTR_PASSWD_SERVER_POLICY:
- if (spw->sp_pwdp)
- free(spw->sp_pwdp);
- /*
- * Note that we don't encrypt the new password.
- * This encryption is done by the NPD client
- * routines
- */
- if (strlen(p->data.val_s) > __NPD2_MAXPASSBYTES)
- return (PWU_DENIED);
-
- (void) strlcpy(newpw, p->data.val_s, sizeof (newpw));
- if ((spw->sp_pwdp = strdup(newpw)) == NULL)
- return (PWU_NOMEM);
- statebuf->proto |= PWU_NEW_PROTO;
- statebuf->hash_pword = 1;
- /*
- * We don't set col_flags since we use the new
- * protocol to update the password
- */
-
- /*
- * In case we need to fall-back on the old protocol,
- * we set the age fields here. Normally the NPD
- * will update this field for us, but using the old
- * update protocol, we need to do it ourselves.
- */
- if (spw->sp_max == 0) {
- /* Forced password change. Disable aging */
- spw->sp_max = -1;
- spw->sp_min = -1;
- }
- spw->sp_lstchg = DAY_NOW_32;
- statebuf->col_flags[COL_PASSWD] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_LOCK_ACCOUNT:
- if (spw->sp_pwdp == NULL) {
- spw->sp_pwdp = LOCKSTRING;
- spw->sp_lstchg = DAY_NOW_32;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->hash_pword = 0;
- statebuf->col_flags[COL_PASSWD] =
- EN_CRYPT|EN_MODIFIED;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- } else if ((strncmp(spw->sp_pwdp, LOCKSTRING,
- sizeof (LOCKSTRING)-1) != 0) &&
- (strcmp(spw->sp_pwdp, NOLOGINSTRING) != 0)) {
- len = sizeof (LOCKSTRING)-1 +
- strlen(spw->sp_pwdp) + 1;
- pword = malloc(len);
- if (pword == NULL) {
- return (PWU_NOMEM);
- }
- (void) strlcpy(pword, LOCKSTRING, len);
- (void) strlcat(pword, spw->sp_pwdp, len);
- free(spw->sp_pwdp);
- spw->sp_pwdp = pword;
- spw->sp_lstchg = DAY_NOW_32;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->hash_pword = 0;
- statebuf->col_flags[COL_PASSWD] =
- EN_CRYPT|EN_MODIFIED;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- }
- break;
-
- case ATTR_UNLOCK_ACCOUNT:
- if (spw->sp_pwdp &&
- strncmp(spw->sp_pwdp, LOCKSTRING,
- sizeof (LOCKSTRING)-1) == 0) {
- (void) strcpy(spw->sp_pwdp,
- spw->sp_pwdp + sizeof (LOCKSTRING)-1);
- spw->sp_lstchg = DAY_NOW_32;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->hash_pword = 0;
- statebuf->col_flags[COL_PASSWD] =
- EN_CRYPT|EN_MODIFIED;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- }
- break;
-
- case ATTR_NOLOGIN_ACCOUNT:
- if (spw->sp_pwdp) {
- free(spw->sp_pwdp);
- }
- if ((spw->sp_pwdp = strdup(NOLOGINSTRING)) == NULL) {
- return (PWU_NOMEM);
- }
- spw->sp_lstchg = DAY_NOW_32;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->hash_pword = 0;
- statebuf->col_flags[COL_PASSWD] =
- EN_CRYPT|EN_MODIFIED;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_EXPIRE_PASSWORD:
- spw->sp_lstchg = 0;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
- case ATTR_GECOS:
- if (pw->pw_gecos)
- free(pw->pw_gecos);
- if ((pw->pw_gecos = strdup(p->data.val_s)) == NULL)
- return (PWU_NOMEM);
- statebuf->proto |= PWU_NEW_PROTO;
- statebuf->col_flags[COL_GECOS] = EN_MODIFIED;
- break;
-
- case ATTR_HOMEDIR:
- if (pw->pw_dir)
- free(pw->pw_dir);
- if ((pw->pw_dir = strdup(p->data.val_s)) == NULL)
- return (PWU_NOMEM);
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_HOMEDIR] = EN_MODIFIED;
- break;
-
- case ATTR_SHELL:
- if (pw->pw_shell)
- free(pw->pw_shell);
- if ((pw->pw_shell = strdup(p->data.val_s)) == NULL)
- return (PWU_NOMEM);
- statebuf->proto |= PWU_NEW_PROTO;
- statebuf->col_flags[COL_SHELL] = EN_MODIFIED;
- break;
-
- case ATTR_LSTCHG:
- spw->sp_lstchg = p->data.val_i;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_MIN:
- if (spw->sp_max == -1 && p->data.val_i != -1 &&
- max_present(p->next) == 0)
- return (PWU_AGING_DISABLED);
- spw->sp_min = p->data.val_i;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_MAX:
- if (p->data.val_i == -1) {
- /* Turn off aging. Reset min and warn too */
- spw->sp_max = spw->sp_min = spw->sp_warn = -1;
- } else {
- /* Turn account aging on */
- if (spw->sp_min == -1) {
- /*
- * minage was not set with command-
- * line option: set to zero
- */
- spw->sp_min = 0;
- }
- /*
- * If aging was turned off, we update lstchg.
- * We take care not to update lstchg if the
- * user has no password, otherwise the user
- * Might not be required to provide a password
- * the next time [s]he logs in.
- */
- if (spw->sp_max == -1 &&
- spw->sp_pwdp != NULL && *spw->sp_pwdp) {
- spw->sp_lstchg = DAY_NOW_32;
- }
- }
- spw->sp_max = p->data.val_i;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_WARN:
- if (spw->sp_max == -1 &&
- p->data.val_i != -1 && max_present(p->next) == 0)
- return (PWU_AGING_DISABLED);
- spw->sp_warn = p->data.val_i;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_INACT:
- spw->sp_inact = p->data.val_i;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_EXPIRE:
- spw->sp_expire = p->data.val_i;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- case ATTR_FLAG:
- spw->sp_flag = p->data.val_i;
- statebuf->proto |= PWU_OLD_PROTO;
- statebuf->col_flags[COL_SHADOW] =
- EN_CRYPT|EN_MODIFIED;
- break;
-
- default:
- break;
- }
- }
-
- return (PWU_SUCCESS);
-}
-
-/*
- * nisplus_update_cred()
- *
- * Update the user's credentials. This routine is called if the
- * old password is different from the old rpc password. In that case,
- * the update though the npd will have changed the password, but not
- * the credentials.
- */
-int
-nisplus_update_cred(char *name, char *oldrpcpw, pwu_repository_t *rep,
- struct statebuf *buf)
-{
- struct passwd *pw;
- char *domain;
- nis_result *cred_res;
- nis_result *handle;
- char short_newpw[DESCREDPASSLEN+1], *short_newpwp = NULL;
-
- entry_col ecol[5];
- nis_object *eobj;
- char mname[NIS_MAXNAMELEN];
- nis_result *mres;
- int reencrypt_tries = 0;
- int reencrypt_success = 0;
- int mod_entry = 0;
-
- int res;
- int i;
- uid_t uid;
-
- if (oldrpcpw == NULL) {
- return (PWU_BAD_CREDPASS);
- }
-
- if (rep && rep->scope)
- domain = rep->scope;
- else
- domain = get_pwd_domain(name, nis_local_directory());
-
- /*
- * a privileged user won't be able to update the user's credentials
- */
- if (nisplus_privileged(name, domain)) {
- return (PWU_NO_PRIV_CRED_UPDATE);
- }
-
- pw = getpwnam_from(name, rep, REP_NISPLUS);
- if (pw == NULL) {
- return (PWU_NOT_FOUND);
- }
-
- uid = pw->pw_uid;
-
- handle = nisplus_handle(name, domain, NISPLUS_UPDATE);
- if (handle == NULL)
- return (PWU_RECOVERY_ERR);
-
- res = nisplus_get_cred(uid, domain, &cred_res);
- if (res != PWU_SUCCESS) {
- return (PWU_SYSTEM_ERROR);
- }
-
- if (cred_res == NULL) {
- return (PWU_SUCCESS);
- }
-
- (void) strlcpy(short_newpw, buf->spwd->sp_pwdp, sizeof (short_newpw));
- short_newpwp = short_newpw;
-
- for (i = 0; i < cred_res->objects.objects_len; i++) {
- nis_object *cred_entry;
- char *oldcryptsecret;
- char *newcryptsecret;
- char *authtype;
- keylen_t keylen;
- algtype_t algtype;
-
- cred_entry = &(cred_res->objects.objects_val[i]);
-
- if (!extract_sec_keyinfo(cred_entry, &oldcryptsecret,
- &authtype, &keylen, &algtype)) {
- continue;
- }
- reencrypt_tries++;
-
- newcryptsecret = reencrypt_secret(oldcryptsecret, oldrpcpw,
- short_newpwp, uid, keylen, algtype);
-
- if (newcryptsecret == NULL) {
- continue;
- }
-
- reencrypt_success++;
-
- /* update cred at server */
- (void) memset((void *)ecol, 0, sizeof (ecol));
- ecol[4].ec_value.ec_value_val = newcryptsecret;
- ecol[4].ec_value.ec_value_len = strlen(newcryptsecret)+1;
- ecol[4].ec_flags = EN_CRYPT|EN_MODIFIED;
- eobj = nis_clone_object(cred_entry, NULL);
- if (eobj == NULL) {
- free(newcryptsecret);
- return (PWU_RECOVERY_ERR);
- }
- eobj->EN_data.en_cols.en_cols_val = ecol;
- eobj->EN_data.en_cols.en_cols_len = 5;
-
- if (snprintf(mname, sizeof (mname),
- "[cname=%s.%s,auth_type=%s],cred.%s", name, domain,
- authtype,
- NIS_RES_OBJECT(handle)->zo_domain) > sizeof (mname)-1) {
- (void) memset(short_newpw, '\0', strlen(short_newpw));
- (void) memset(oldrpcpw, '\0', strlen(oldrpcpw));
- free(newcryptsecret);
- return (PWU_RECOVERY_ERR);
- }
-
- if (mname[strlen(mname) - 1] != '.' &&
- strlcat(mname, ".", sizeof (mname)) >= sizeof (mname)) {
- free(newcryptsecret);
- return (PWU_RECOVERY_ERR);
- }
-
- mres = nis_modify_entry(mname, eobj, 0);
- if (mres->status == NIS_SUCCESS)
- mod_entry++;
-
- free(newcryptsecret);
-
- /* set column stuff to NULL to that we can free eobj */
- eobj->EN_data.en_cols.en_cols_val = NULL;
- eobj->EN_data.en_cols.en_cols_len = 0;
- (void) nis_destroy_object(eobj);
- (void) nis_freeresult(mres);
- }
-
- (void) memset(short_newpw, '\0', strlen(short_newpw));
- short_newpwp = NULL;
- (void) memset(oldrpcpw, '\0', strlen(oldrpcpw));
-
- if (reencrypt_tries > 0 && mod_entry == 0) {
- return (PWU_RECOVERY_ERR);
- }
-
- if (mod_entry < reencrypt_tries) {
- return (PWU_UPDATED_SOME_CREDS);
- }
- return (PWU_SUCCESS);
-}
-
-
-/*
- * nisplus_new_proto(name, oldpw, oldrpcpw, rep, buf)
- *
- * Implement NIS+ attribute updates using the NIS+ Password Daemon (NPD)
- * This routine is used to update passwd, gecos and shell attributes
- */
-int
-nisplus_new_proto(char *name, char *oldpw, char *oldrpcpw,
- pwu_repository_t *rep, void *buf)
-{
- struct statebuf *statebuf;
- CLIENT *clnt = NULL;
-
- /* pointers to possibly updated fields */
- char *newpass;
- char *gecos;
- char *shell;
-
- /* NIS+ server key material */
- char *srv_pubkey = NULL;
- char *key_type = NULL;
- keylen_t srv_keylen;
- algtype_t srv_keyalgtype;
-
- /* User key material */
- uchar_t *u_pubkey = NULL;
- char *u_seckey = NULL;
-
- des_block deskeys[3];
- uint32_t ident = 0;
- uint32_t randval = 0;
- int error = 0;
- int retval;
- int npd_res;
- nispasswd_error *errlist = NULL;
- char short_opass[DESCREDPASSLEN+1], *short_opassp = NULL;
-
- statebuf = (struct statebuf *)buf;
-
- if (npd_makeclnthandle(statebuf->domain, &clnt, &srv_pubkey,
- &srv_keylen, &srv_keyalgtype, &key_type) == FALSE) {
- syslog(LOG_ERR,
- "Couldn't make a client handle to NIS+ password daemon");
- retval = PWU_RECOVERY_ERR;
- goto out;
- }
-
- if ((u_pubkey = malloc(BITS2NIBBLES(srv_keylen) + 1)) == NULL) {
- retval = PWU_NOMEM;
- goto out;
- }
-
- if ((u_seckey = malloc(BITS2NIBBLES(srv_keylen) + 1)) == NULL) {
- retval = PWU_NOMEM;
- goto out;
- }
-
- (void) strlcpy(short_opass, oldpw, sizeof (short_opass));
- short_opassp = short_opass;
-
- /* Generate a key-pair for this user */
- if (__gen_dhkeys_g((char *)u_pubkey, u_seckey, srv_keylen,
- srv_keyalgtype, short_opassp) == 0) {
- syslog(LOG_ERR, "Couldn't create a D-H key-pair "
- "(len = %d, type = %d)", srv_keylen, srv_keyalgtype);
- retval = PWU_RECOVERY_ERR;
- goto out;
- }
-
- /*
- * Get the common DES key(s) from the server's pubkey and the
- * user's secret key
- */
- if (__gen_common_dhkeys_g(srv_pubkey, u_seckey, srv_keylen,
- srv_keyalgtype, deskeys,
- AUTH_DES_KEY(srv_keylen, srv_keyalgtype) ? 1 : 3) == 0) {
- syslog(LOG_ERR, "Couldn't get a common DES key "
- "(keylen = %d, algtype = %d)", srv_keylen, srv_keyalgtype);
- retval = PWU_RECOVERY_ERR;
- goto out;
- }
-
- /*
- * Must preserve password length here since NPD decrypts the login
- * password as part of the authentication.
- */
- npd_res = nispasswd_auth(name, statebuf->domain, oldpw, u_pubkey,
- key_type, srv_keylen, srv_keyalgtype, deskeys, clnt, &ident,
- &randval, &error);
-
- if (npd_res == NPD_FAILED) {
- if (error >= 0 &&
- error < sizeof (npd_errmsg) / sizeof (npd_errmsg[0]))
- syslog(LOG_ALERT, "%s", npd_errmsg[error]);
- else
- syslog(LOG_ALERT, "NIS+ fatal error: %d", error);
-
- if (error == NPD_INVALIDARGS) {
- retval = PWU_RECOVERY_ERR;
- } else if (error == NPD_PASSINVALID) {
- retval = PWU_DENIED;
- } else {
- syslog(LOG_ALERT, "Failover to old protocol");
- /*
- * we need to tell the old protocol to update
- * the password and the age fields.
- */
- statebuf->col_flags[COL_SHADOW] = EN_CRYPT|EN_MODIFIED;
- retval = nisplus_old_proto(name, oldpw, oldrpcpw,
- rep, buf);
- }
- goto out;
- } else if (npd_res == NPD_TRYAGAIN) {
- /*
- * Since the the non-privileged user's password has already
- * been verified, we only get here if the privileged user
- * entered a wrong NIS+ administrator password.
- * The origional passwd requested administrator
- * password again. We bail-out instead.
- */
- retval = PWU_RECOVERY_ERR;
- goto out;
- }
-
- if (statebuf->col_flags[COL_PASSWD] & EN_MODIFIED)
- newpass = statebuf->spwd->sp_pwdp;
- else
- newpass = oldpw; /* we're updating attributes */
-
- if (statebuf->col_flags[COL_GECOS] & EN_MODIFIED)
- gecos = statebuf->pwd->pw_gecos;
- else
- gecos = NULL;
- if (statebuf->col_flags[COL_SHELL] & EN_MODIFIED)
- shell = statebuf->pwd->pw_shell;
- else
- shell = NULL;
-
- npd_res = nispasswd_pass(clnt, ident, randval, &deskeys[0],
- newpass, gecos, shell, &error, &errlist);
-
- if (npd_res == NPD_FAILED) {
- retval = PWU_RECOVERY_ERR;
- } else if (npd_res == NPD_PARTIALSUCCESS) {
- if (statebuf->col_flags[COL_PASSWD] & EN_MODIFIED) {
- /*
- * This can only indicate that the server
- * failed to update the credentials (SECRETKEY).
- * We therefore try to update the credentials directly.
- */
- retval = nisplus_update_cred(name,
- oldrpcpw ? oldrpcpw : short_opassp, rep, buf);
- } else {
- /* We don't update creds for gecos/shell updates */
- retval = PWU_SUCCESS;
- }
- } else {
- retval = PWU_SUCCESS;
- }
- __npd_free_errlist(errlist);
-
-out:
- if (u_pubkey) free(u_pubkey);
- if (u_seckey) free(u_seckey);
- if (srv_pubkey) free(srv_pubkey);
- if (key_type) free(key_type);
-
- if (clnt) {
- auth_destroy(clnt->cl_auth);
- clnt_destroy(clnt);
- }
- return (retval);
-}
-
-/*
- * nisplus_old_proto(name, oldpw, oldrpcpw, rep, buf)
- *
- * Update account attributes using the nis_tables(3NSL) interface
- */
-int
-nisplus_old_proto(char *name, char *oldpw, char *oldrpcpw,
- pwu_repository_t *rep, void *buf)
-{
- entry_col ecol[8];
- struct statebuf *statebuf;
- struct passwd *pw;
- struct spwd *spw;
- int *col_flags;
- char shadow[80]; /* 80 is also used in rpc.nispasswdd/npd_svc.c */
- nis_object *eobj;
- nis_result *result;
- char key[NIS_MAXNAMELEN];
- nis_result *handle;
- int pw_changed = 0; /* indicates whether we should update creds */
- int retval;
- char short_opass[DESCREDPASSLEN+1], *short_opassp = NULL;
-
- (void) strlcpy(short_opass, oldpw, sizeof (short_opass));
- short_opassp = short_opass;
- statebuf = (struct statebuf *)buf;
- pw = statebuf->pwd;
- spw = statebuf->spwd;
- col_flags = statebuf->col_flags;
-
- handle = nisplus_handle(name, statebuf->domain, NISPLUS_UPDATE);
-
- if (handle == NULL)
- return (PWU_RECOVERY_ERR);
-
- (void) memset(ecol, 0, sizeof (ecol));
-
-#define EC_VAL ec_value.ec_value_val
-#define EC_LEN ec_value.ec_value_len
-
- if (col_flags[COL_PASSWD]) {
- if (statebuf->hash_pword) {
- char *salt;
- salt = crypt_gensalt(spw->sp_pwdp, pw);
-
- if (salt == NULL) {
- if (errno == ENOMEM)
- return (PWU_NOMEM);
- else {
- /* algorithm problem? */
- syslog(LOG_AUTH | LOG_ALERT,
- "passwdutil: crypt_gensalt "
- "%m");
- return (PWU_UPDATE_FAILED);
- }
- }
- ecol[COL_PASSWD].EC_VAL = crypt(spw->sp_pwdp, salt);
- free(salt);
- pw_changed = 1;
- } else {
- ecol[COL_PASSWD].EC_VAL = strdup(spw->sp_pwdp);
- }
- ecol[COL_PASSWD].EC_LEN = strlen(ecol[COL_PASSWD].EC_VAL) + 1;
- ecol[COL_PASSWD].ec_flags = col_flags[COL_PASSWD];
- }
- if (col_flags[COL_GECOS]) {
- ecol[COL_GECOS].EC_VAL = pw->pw_gecos;
- ecol[COL_GECOS].EC_LEN = strlen(pw->pw_gecos) + 1;
- ecol[COL_GECOS].ec_flags = col_flags[COL_GECOS];
- }
- if (col_flags[COL_HOMEDIR]) {
- ecol[COL_HOMEDIR].EC_VAL = pw->pw_dir;
- ecol[COL_HOMEDIR].EC_LEN = strlen(pw->pw_dir) + 1;
- ecol[COL_HOMEDIR].ec_flags = col_flags[COL_HOMEDIR];
- }
- if (col_flags[COL_SHELL]) {
- ecol[COL_SHELL].EC_VAL = pw->pw_shell;
- ecol[COL_SHELL].EC_LEN = strlen(pw->pw_shell) + 1;
- ecol[COL_SHELL].ec_flags = col_flags[COL_SHELL];
- }
- if (col_flags[COL_SHADOW]) {
- if (spw->sp_expire != -1) {
- (void) snprintf(shadow, sizeof (shadow),
- "%d:%d:%d:%d:%d::%u",
- spw->sp_lstchg, spw->sp_min, spw->sp_max,
- spw->sp_warn, spw->sp_inact, spw->sp_flag);
- } else {
- (void) snprintf(shadow, sizeof (shadow),
- "%d:%d:%d:%d:%d:%d:%u",
- spw->sp_lstchg, spw->sp_min, spw->sp_max,
- spw->sp_warn, spw->sp_inact, spw->sp_expire,
- spw->sp_flag);
- }
- ecol[COL_SHADOW].EC_VAL = shadow;
- ecol[COL_SHADOW].EC_LEN = strlen(shadow) + 1;
- ecol[COL_SHADOW].ec_flags = col_flags[COL_SHADOW];
- }
-
- if ((eobj = nis_clone_object(NIS_RES_OBJECT(handle), NULL)) == NULL) {
- syslog(LOG_ERR, "NIS+ clone object failed");
- return (PWU_RECOVERY_ERR);
- }
-
- eobj->EN_data.en_cols.en_cols_val = ecol;
- eobj->EN_data.en_cols.en_cols_len = 8;
-
- if (snprintf(key, sizeof (key), "[name=%s],%s.%s", name,
- NIS_RES_OBJECT(handle)->zo_name,
- NIS_RES_OBJECT(handle)->zo_domain) >= sizeof (key) - 1) {
- syslog(LOG_ERR, "NIS+ name too long");
- retval = PWU_NOMEM;
- goto out;
- }
-
- if (key[strlen(key) - 1] != '.')
- (void) strcat(key, ".");
-
-again:
- result = nis_modify_entry(key, eobj, 0);
-
- /*
- * It is possible that we have permission to modify the
- * encrypted password but not the shadow column in the
- * NIS+ table. In this case, we should try updating only
- * the password field and not the aging stuff (lstchg).
- * With the current NIS+ passwd table format, this would
- * be the case most of the times.
- */
- if (result->status == NIS_PERMISSION &&
- ecol[COL_SHADOW].ec_flags != 0) {
- ecol[COL_SHADOW].ec_flags = 0;
- goto again;
- } else if (result->status != NIS_SUCCESS) {
- syslog(LOG_ERR, "NIS+ password information update failed\n");
- retval = PWU_ATTR_UPDATE_ERR;
- } else {
- retval = PWU_SUCCESS;
- }
- eobj->EN_data.en_cols.en_cols_val = NULL;
- eobj->EN_data.en_cols.en_cols_len = 0;
- (void) nis_destroy_object(eobj);
- if (result)
- (void) nis_freeresult(result);
- result = NULL;
-out:
- if (ecol[COL_PASSWD].EC_VAL)
- free(ecol[COL_PASSWD].EC_VAL);
-
- if (pw_changed == 1 && retval == PWU_SUCCESS)
- retval = nisplus_update_cred(name, oldrpcpw ? oldrpcpw
- : short_opassp, rep, buf);
-
- return (retval);
-
-#undef EC_VAL
-#undef EC_LEN
-}
-/*
- * nis_putpwnam(name, oldpw, oldrpcpw, rep, buf)
- *
- * update the NIS+ server using the appropriate protocol(s) for the
- * attributes that have changed.
- */
-int
-nisplus_putpwnam(char *name, char *oldpw, char *oldrpcpw,
- pwu_repository_t *rep, void *buf)
-{
- struct statebuf *statebuf;
- int result = PWU_SUCCESS;
- uid_t cur_euid;
- char short_rpcpw[_PASS_MAX_XPG+1];
- char *short_rpcpwptr = NULL;
- char pw[_PASS_MAX+1];
- char *pw_ptr = NULL;
-
- if (strcmp(name, "root") == 0)
- return (PWU_NOT_FOUND);
-
- if (oldpw) {
- (void) strlcpy(pw, oldpw, sizeof (pw));
- pw_ptr = pw;
- } else /* oldpw is NULL. rpc.nispasswdd non-responsive ??? */
- return (PWU_RECOVERY_ERR);
-
- if (oldrpcpw) {
- (void) strlcpy(short_rpcpw, oldrpcpw, sizeof (short_rpcpw));
- short_rpcpwptr = short_rpcpw;
- } else
- return (PWU_RECOVERY_ERR);
-
- statebuf = (struct statebuf *)buf;
-
- if (statebuf->proto & PWU_OLD_PROTO) {
- result = nisplus_old_proto(name, pw_ptr,
- short_rpcpwptr, rep, buf);
- }
-
- if (result == PWU_SUCCESS && (statebuf->proto & PWU_NEW_PROTO)) {
- cur_euid = geteuid();
- if (getuid() != 0)
- (void) seteuid(getuid());
-
- result = nisplus_new_proto(name, pw_ptr,
- short_rpcpwptr, rep, buf);
- (void) seteuid(cur_euid);
- }
-
- return (result);
-}
-
-
-/*
- * Given a cred table entry, return the secret key, auth type, key length
- * of secret key, and algorithm type of secret key.
- *
- * The type of key must be listed in the NIS+ security cf.
- *
- * Return TRUE on success and FALSE on failure.
- */
-int
-extract_sec_keyinfo(
- nis_object *cred_entry,
- char **seckey,
- char **authtype,
- keylen_t *keylen,
- algtype_t *algtype)
-{
- char mechalias[MECH_MAXALIASNAME+1];
-
- if ((*authtype = ENTRY_VAL(cred_entry, 1)) == NULL) {
- syslog(LOG_ERR, "auth type field is empty for cred entry");
- return (0);
- }
-
- /* Don't need the "local" unix system cred. */
- if (strncmp(*authtype, "LOCAL", sizeof ("LOCAL")) == 0) {
- return (0);
- }
-
- if (!__nis_authtype2mechalias(*authtype, mechalias,
- sizeof (mechalias))) {
- syslog(LOG_ERR,
- "can't convert authtype '%s' to mechanism alias",
- *authtype);
- return (0);
- }
-
- /* Make sure the mech is in the NIS+ security cf. */
- if (__nis_translate_mechanism(mechalias, keylen, algtype) < 0) {
- syslog(LOG_WARNING,
- "can't convert mechanism alias '%s' to keylen and algtype",
- mechalias);
- return (0);
- }
-
- if ((*seckey = ENTRY_VAL(cred_entry, 4)) == NULL) {
- return (0);
- }
-
- return (1);
-}
-
-int
-nisplus_get_cred(uid_t uid, char *domain, nis_result **cred_res)
-{
- char buf[NIS_MAXNAMELEN + 1];
- int namelen;
- struct nis_result *local_res;
- nis_name cred_domain;
- char *local_cname;
-
- *cred_res = NULL;
-
- namelen = snprintf(buf, sizeof (buf),
- "[auth_name=%d,auth_type=LOCAL],%s.%s",
- (int)uid, PKTABLE, domain);
- if (namelen >= sizeof (buf)) {
- syslog(LOG_ERR, "nisplus_get_cred: name too long");
- return (PWU_SYSTEM_ERROR);
- }
- if (buf[namelen-1] != '.')
- (void) strcat(buf, ".");
-
- local_res = nis_list(buf, USE_DGRAM + FOLLOW_LINKS + FOLLOW_PATH +
- MASTER_ONLY, NULL, NULL);
-
- if (local_res == NULL || local_res->status != NIS_SUCCESS) {
- if (local_res)
- nis_freeresult(local_res);
- return (PWU_SUCCESS);
- }
-
- local_cname = ENTRY_VAL(NIS_RES_OBJECT(local_res), 0);
- if (local_cname == NULL) {
- nis_freeresult(local_res);
- return (PWU_CRED_ERROR);
- }
-
- cred_domain = nis_domain_of(local_cname);
-
- namelen = snprintf(buf, sizeof (buf),
- "[cname=%s],%s.%s", /* get all entries for user */
- local_cname, PKTABLE, cred_domain);
-
- if (namelen >= sizeof (buf)) {
- syslog(LOG_ERR, "nisplus_get_cred: cname too long");
- *cred_res = NULL;
- nis_freeresult(local_res);
- return (PWU_SYSTEM_ERROR);
- }
-
- nis_freeresult(local_res);
-
- *cred_res = nis_list(buf, USE_DGRAM + FOLLOW_LINKS + FOLLOW_PATH +
- MASTER_ONLY, NULL, NULL);
-
- return (PWU_SUCCESS);
-}
-
-int
-nisplus_getnetnamebyuid(char *name, uid_t uid)
-{
- if (uid == 0)
- return (host2netname(name, (char *)NULL, (char *)NULL));
- else
- return (user2netname(name, uid, (char *)NULL));
-}
-
-/*
- * oldpw was truncated in pam_dhkeys' pam_sm_chauthtok.
- */
-int
-nisplus_verify_rpc_passwd(char *name, char *oldpw, pwu_repository_t *rep)
-{
- int res;
- int i;
- int success_cnt;
- struct passwd *pw;
- char *domain;
- nis_result *cred_res;
-
- if (strcmp(name, "root") == 0)
- return (PWU_SUCCESS);
-
- /* We need the user's uid */
- pw = getpwnam_from(name, rep, REP_NISPLUS);
- if (pw == NULL)
- return (PWU_NOT_FOUND);
-
- if (rep && rep->scope)
- domain = rep->scope;
- else
- domain = get_pwd_domain(name, nis_local_directory());
-
- if (nisplus_privileged(name, domain)) {
- /* privileged user; don't ask for old RPC password */
- return (PWU_SUCCESS);
- }
-
- if (oldpw == NULL)
- return (PWU_CRED_ERROR);
-
- res = nisplus_get_cred(pw->pw_uid, domain, &cred_res);
-
- if (res != PWU_SUCCESS)
- return (PWU_SYSTEM_ERROR);
-
- if (cred_res == NULL)
- return (PWU_CRED_ERROR);
-
- /*
- * Decrypt each of the credentials found with the oldpw.
- * count the number of succesfull decrypts.
- */
- success_cnt = 0;
-
- for (i = 0; i < cred_res->objects.objects_len; i++) {
- nis_object *entry = &(cred_res->objects.objects_val[i]);
- char *auth;
- char *key;
- keylen_t keylen;
- algtype_t alg;
- char netname[MAXNETNAMELEN+1];
- char *tmpkey;
-
- if (!extract_sec_keyinfo(entry, &key, &auth, &keylen, &alg))
- continue;
-
- if (!nisplus_getnetnamebyuid(netname, pw->pw_uid)) {
- syslog(LOG_ERR, "nisplus_verify_rpc_passwd: "
- "Can't get netname");
- continue;
- }
- if ((tmpkey = strdup(key)) == NULL)
- return (PWU_NOMEM);
-
- if (xdecrypt_g(tmpkey, keylen, alg, oldpw, netname, TRUE))
- success_cnt++;
-
- free(tmpkey);
- }
-
- if (success_cnt)
- return (PWU_SUCCESS);
- else
- return (PWU_BAD_CREDPASS);
-}
-
-char *
-reencrypt_secret(char *oldsec, char *oldpass, char *newpass,
- uid_t uid, keylen_t keylen, algtype_t algtype)
-{
- char netname[MAXNETNAMELEN+1];
- char *newsec;
-
- if (nisplus_getnetnamebyuid(netname, uid) == 0) {
- return (NULL);
- }
-
- if (!xdecrypt_g(oldsec, keylen, algtype, oldpass, netname, TRUE)) {
- syslog(LOG_INFO, "secret key decrypt failed for %s/%d-%d",
- netname, keylen, algtype);
- return (NULL);
- }
-
- if (!xencrypt_g(oldsec, keylen, algtype, newpass, netname,
- &newsec, TRUE)) {
- syslog(LOG_ERR, "secret key encrypt failed for user %s/%d-%d",
- netname, keylen, algtype);
- return (NULL);
- }
-
- return (newsec);
-}
diff --git a/usr/src/lib/passwdutil/npd_clnt.c b/usr/src/lib/passwdutil/npd_clnt.c
deleted file mode 100644
index 2b5159df2d..0000000000
--- a/usr/src/lib/passwdutil/npd_clnt.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * 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
- * or http://www.opensolaris.org/os/licensing.
- * 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 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * npd_clnt.c
- * Contains all the client-side routines to communicate
- * with the NIS+ passwd update deamon.
- *
- */
-
-#include <stdlib.h>
-#include <syslog.h>
-#include <string.h>
-#include <shadow.h>
-#include <rpc/rpc.h>
-#include <rpc/xdr.h>
-#include <rpc/des_crypt.h>
-#include <mp.h>
-#include <rpc/key_prot.h>
-#include <rpcsvc/nis.h>
-#include <rpcsvc/nispasswd.h>
-#include <rpcsvc/nis_dhext.h>
-#include <memory.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#define _NPD_PASSMAXLEN 16
-
-extern bool_t __npd_ecb_crypt(uint32_t *, uint32_t *,
- des_block *, unsigned int, unsigned int,
- des_block *);
-extern bool_t __npd_cbc_crypt(uint32_t *, char *, unsigned int,
- npd_newpass *, unsigned int, unsigned int,
- des_block *);
-extern bool_t __npd2_cbc_crypt(uint32_t *, char *, unsigned int,
- npd_newpass2 *, unsigned int, unsigned int,
- des_block *);
-rpcvers_t clnt_vers = NISPASSWD_VERS2;
-
-/*
- * Loop thru the NIS+ security cf entries until one DH(EXT) mech key is
- * successfully extracted from the server DHEXT netobj. Copy the hex key
- * string to newly allocated memory and return it's address in 'keybuf'.
- * The caller must free this memory. Also, dup the key length and algtype
- * "alias" string and return it's address in keystr (which the caller
- * must also free on successful return).
- *
- * Policy: If no valid cf entries exist or if the entry is the "des" compat
- * one, then try it and then end search.
- *
- * Returns TRUE on success and FALSE on failure.
- */
-static bool_t
-get_dhext_key(
- netobj *pkey, /* in */
- char **keybuf, /* out */
- keylen_t *keylen, /* (bits) out */
- algtype_t *keyalgtype, /* out */
- char **keystr) /* out */
-{
- mechanism_t **mechs; /* list of mechanisms */
- char *hexkey; /* hex public key */
-
- if (mechs = __nis_get_mechanisms(FALSE)) {
- mechanism_t **mpp;
-
- for (mpp = mechs; *mpp; mpp++) {
- mechanism_t *mp = *mpp;
-
- if (AUTH_DES_COMPAT_CHK(mp)) {
- __nis_release_mechanisms(mechs);
- goto try_auth_des;
- }
- if (! VALID_MECH_ENTRY(mp))
- continue;
-
- if (hexkey = __nis_dhext_extract_pkey(pkey,
- mp->keylen, mp->algtype)) {
- if ((*keybuf = malloc(strlen(hexkey) + 1))
- == 0) {
- syslog(LOG_ERR, "malloc failed");
- continue; /* try next mech */
- }
- (void) strcpy(*keybuf, hexkey);
- *keylen = mp->keylen;
- *keyalgtype = mp->algtype;
- *keystr = strdup(mp->alias);
- __nis_release_mechanisms(mechs);
- return (TRUE);
- } else
- continue;
- }
- __nis_release_mechanisms(mechs);
- return (FALSE);
- } else {
-
- /* no valid cf mech entries or AUTH_DES compat entry found */
- try_auth_des:
- if (hexkey = __nis_dhext_extract_pkey(pkey,
- AUTH_DES_KEYLEN, AUTH_DES_ALGTYPE)) {
- if ((*keybuf = malloc(strlen(hexkey) + 1)) == NULL) {
- syslog(LOG_ERR, "malloc failed");
- return (FALSE);
- }
- (void) strcpy(*keybuf, hexkey);
- *keylen = AUTH_DES_KEYLEN;
- *keyalgtype = AUTH_DES_ALGTYPE;
- *keystr = strdup(NIS_SEC_CF_DES_ALIAS);
- return (TRUE);
- }
- }
- return (FALSE);
-}
-
-
-
-/*
- * given the domain return the client handle to the rpc.nispasswdd
- * that I need to contact and the master_servers' publickey and the
- * the key length and algtype "alias" string.
- *
- * returns TRUE on success and FALSE on failure.
- *
- * on successful return, caller must free the srv_pubkey buf and
- * the keystr buf.
- */
-bool_t
-npd_makeclnthandle(domain, clnt, srv_pubkey,
- srv_keylen, srv_keyalgtype, key_type)
-char *domain;
-CLIENT **clnt; /* out */
-char **srv_pubkey; /* buf to hold the pubkey; out */
-keylen_t *srv_keylen; /* server key lenth (bits); out */
-algtype_t *srv_keyalgtype; /* server key algorithm type; out */
-char **key_type; /* key length/algtype str buf; out */
-{
- nis_server **srvs; /* servers that serve 'domain' */
- nis_server *master_srv;
- char buf[NIS_MAXNAMELEN];
- CLIENT *tmpclnt = NULL;
- rpcvers_t vers;
-
- if (domain == NULL || *domain == '\0')
- domain = nis_local_directory();
-
- /* strlen("org_dir.") + null + "." = 10 */
- if ((strlen(domain) + 10) > (size_t)NIS_MAXNAMELEN)
- return (FALSE);
- (void) snprintf(buf, sizeof (buf), "org_dir.%s", domain);
- if (buf[strlen(buf) - 1] != '.')
- (void) strcat(buf, ".");
-
- srvs = nis_getservlist(buf);
- if (srvs == NULL) {
- /* can't find any of the servers that serve this domain */
- /* something is very wrong ! */
- syslog(LOG_ERR,
- "can't get a list of servers for %s domain",
- domain);
- return (FALSE);
- }
- master_srv = srvs[0]; /* the first one is always the master */
-
- /*
- * copy a publickey
- */
- switch (master_srv->key_type) {
- case NIS_PK_DHEXT:
- if (!get_dhext_key(&(master_srv->pkey), srv_pubkey,
- srv_keylen, srv_keyalgtype,
- key_type)) {
- syslog(LOG_WARNING,
- "could not get a DHEXT public key for master server '%s'",
- master_srv->name);
- (void) nis_freeservlist(srvs);
- return (FALSE);
- }
- break;
-
- case NIS_PK_DH:
- if ((*srv_pubkey = malloc(master_srv->pkey.n_len)) == NULL) {
- syslog(LOG_ERR, "malloc failed");
- (void) nis_freeservlist(srvs);
- return (FALSE);
- }
- (void) strcpy(*srv_pubkey, master_srv->pkey.n_bytes);
- *srv_keylen = AUTH_DES_KEYLEN;
- *srv_keyalgtype = AUTH_DES_ALGTYPE;
- *key_type = strdup(AUTH_DES_AUTH_TYPE);
- break;
-
- case NIS_PK_NONE:
- default:
- /* server does not have a D-H key-pair */
- syslog(LOG_ERR, "no publickey for %s", master_srv->name);
- (void) nis_freeservlist(srvs);
- return (FALSE);
- }
-
- /*
- * now that we have the universal addr for the master server,
- * lets create the client handle to rpc.nispasswdd.
- * always use VC and attempt to create an authenticated handle.
- * nis_make_rpchandle() will attempt to use auth_des first,
- * if user does not have D-H keys, then it will try auth_sys.
- * sendsz and recvsz are 0 ==> choose defaults.
- *
- * First try NISPASSWD_VERS2. If it fails, fallback to NISPASSWD_VERS
- */
- for (vers = NISPASSWD_VERS2;
- (vers >= NISPASSWD_VERS) && (tmpclnt == NULL); vers--) {
- tmpclnt = nis_make_rpchandle_gss_svc_ruid(master_srv, 0,
- NISPASSWD_PROG, vers, ZMH_VC+ZMH_AUTH, 0,
- 0, NULL, NIS_SVCNAME_NISPASSWD);
- clnt_vers = vers;
- }
-
- /* done with server list */
- (void) nis_freeservlist(srvs);
- if (tmpclnt == NULL) {
- /*
- * error syslog'd by nis_make_rpchandle()
- */
- return (FALSE);
- }
- *clnt = tmpclnt;
- return (TRUE);
-}
-
-/* Default timeout can be changed using clnt_control() */
-static struct timeval TIMEOUT = { 55, 0 };
-
-/*
- * initiate the passwd update request session by sending
- * username, domainname, the generated public key and
- * the callers' old passwd encrypted with the common DES key.
- * if it succeeds, decrypt the identifier and randval sent in
- * the response; otherwise return an appropriate error code.
- */
-nispasswd_status
-nispasswd_auth(user, domain, oldpass, u_pubkey, key_type, keylen,
- algtype, deskeys, clnt, ident, randval, err)
-char *user; /* user name */
-char *domain; /* domain */
-char *oldpass; /* clear old password */
-uchar_t *u_pubkey; /* users' public key */
-char *key_type; /* key len and alg type string */
-keylen_t keylen; /* user's public key length */
-algtype_t algtype; /* user's public key algorithm type */
-des_block *deskeys; /* the common DES key */
-CLIENT *clnt; /* client handle to rpc.nispasswdd */
-uint32_t *ident; /* ID, returned on first attempt */
-uint32_t *randval; /* R, returned on first attempt */
-int *err; /* error code, returned */
-{
- npd_request req_arg;
- nispasswd_authresult res;
- des_block ivec;
- unsigned char xpass[_NPD_PASSMAXLEN+1];
- unsigned char xpass2[__NPD2_MAXPASSBYTES+1];
- des_block cryptbuf;
- int cryptstat;
- int i;
-
- if ((user == NULL || *user == '\0') ||
- (domain == NULL || *domain == '\0') ||
- (oldpass == NULL || *oldpass == '\0') ||
- (u_pubkey == NULL || *u_pubkey == '\0') ||
- (deskeys == (des_block *) NULL) ||
- (clnt == (CLIENT *) NULL)) {
- *err = NPD_INVALIDARGS;
- return (NPD_FAILED);
- }
- (void) memset((char *)&req_arg, 0, sizeof (req_arg));
- (void) memset((char *)&res, 0, sizeof (res));
-
- if (clnt_vers == NISPASSWD_VERS) {
- /* encrypt the passwd with the common des key */
- if (strlen(oldpass) > (size_t)_NPD_PASSMAXLEN) {
- *err = NPD_BUFTOOSMALL;
- return (NPD_FAILED);
- }
- (void) strlcpy((char *)xpass, oldpass, sizeof (xpass));
- for (i = strlen(oldpass); i < _NPD_PASSMAXLEN; i++)
- xpass[i] = '\0';
-
- ivec.key.high = ivec.key.low = 0;
- if (AUTH_DES_KEY(keylen, algtype))
- cryptstat = cbc_crypt((char *)deskeys[0].c,
- (char *)xpass, _NPD_PASSMAXLEN,
- DES_ENCRYPT | DES_HW, (char *)&ivec);
- else
- cryptstat = __cbc_triple_crypt(deskeys, (char *)xpass,
- _NPD_PASSMAXLEN, DES_ENCRYPT | DES_HW,
- (char *)&ivec);
-
- if (DES_FAILED(cryptstat)) {
- *err = NPD_ENCRYPTFAIL;
- return (NPD_FAILED);
- }
- } else {
- /* encrypt the passwd with the common des key */
- if (strlen(oldpass) > (size_t)__NPD2_MAXPASSBYTES) {
- *err = NPD_BUFTOOSMALL;
- return (NPD_FAILED);
- }
- (void) strlcpy((char *)xpass2, oldpass, sizeof (xpass2));
- for (i = strlen(oldpass); i < __NPD2_MAXPASSBYTES; i++)
- xpass2[i] = '\0';
-
- ivec.key.high = ivec.key.low = 0;
- if (AUTH_DES_KEY(keylen, algtype))
- cryptstat = cbc_crypt((char *)deskeys[0].c,
- (char *)xpass2, __NPD2_MAXPASSBYTES,
- DES_ENCRYPT | DES_HW, (char *)&ivec);
- else
- cryptstat = __cbc_triple_crypt(deskeys, (char *)xpass2,
- __NPD2_MAXPASSBYTES,
- DES_ENCRYPT | DES_HW, (char *)&ivec);
-
- if (DES_FAILED(cryptstat)) {
- *err = NPD_ENCRYPTFAIL;
- return (NPD_FAILED);
- }
- }
-
- req_arg.username = user;
- req_arg.domain = domain;
- req_arg.key_type = key_type;
- req_arg.user_pub_key.user_pub_key_len =
- strlen((char *)u_pubkey) + 1;
- req_arg.user_pub_key.user_pub_key_val = u_pubkey;
- if (clnt_vers == NISPASSWD_VERS) {
- req_arg.npd_authpass.npd_authpass_len = _NPD_PASSMAXLEN;
- req_arg.npd_authpass.npd_authpass_val = xpass;
- } else {
- req_arg.npd_authpass.npd_authpass_len = __NPD2_MAXPASSBYTES;
- req_arg.npd_authpass.npd_authpass_val = xpass2;
- }
- req_arg.ident = *ident; /* on re-tries ident is non-zero */
-
- if (clnt_call(clnt, NISPASSWD_AUTHENTICATE,
- (xdrproc_t)xdr_npd_request, (caddr_t)&req_arg,
- (xdrproc_t)xdr_nispasswd_authresult, (caddr_t)&res,
- TIMEOUT) != RPC_SUCCESS) {
-
- /* following msg is printed on stderr */
- (void) clnt_perror(clnt,
- "authenticate call to rpc.nispasswdd failed");
- *err = NPD_SRVNOTRESP;
- return (NPD_FAILED);
- }
-
- switch (res.status) {
- case NPD_SUCCESS:
- case NPD_TRYAGAIN:
- /*
- * decrypt the ident & randval
- */
- cryptbuf.key.high =
- ntohl(res.nispasswd_authresult_u.npd_verf.npd_xid);
- cryptbuf.key.low =
- ntohl(res.nispasswd_authresult_u.npd_verf.npd_xrandval);
-
- if (! __npd_ecb_crypt(ident, randval, &cryptbuf,
- sizeof (des_block), DES_DECRYPT, &(deskeys[0]))) {
- *err = NPD_DECRYPTFAIL;
- return (NPD_FAILED);
- }
- return (res.status);
-
- case NPD_FAILED:
- *err = res.nispasswd_authresult_u.npd_err;
- return (NPD_FAILED);
- default:
- /*
- * should never reach this case !
- */
- *err = NPD_SYSTEMERR;
- return (NPD_FAILED);
- }
- /* NOTREACHED */
-}
-
-/*
- * authenticated the caller, now send the identifier; and the
- * new password and the random value encrypted with the common
- * DES key. Send any other changed password information in the
- * clear.
- */
-int
-nispasswd_pass(clnt, ident, randval, deskey, newpass, gecos, shell, err, errlst)
-CLIENT *clnt; /* client handle to rpc.nispasswdd */
-uint32_t ident; /* ID */
-uint32_t randval; /* R */
-des_block *deskey; /* common DES key */
-char *newpass; /* clear new password */
-char *gecos; /* gecos */
-char *shell; /* shell */
-int *err; /* error code, returned */
-nispasswd_error **errlst; /* error list on partial success, returned */
-{
- npd_update send_arg;
- npd_update2 send_arg2;
- nispasswd_updresult result;
- npd_newpass cryptbuf1;
- npd_newpass2 cryptbuf2;
- unsigned int tmp_xrval;
- unsigned int tmp_npd_pad;
- nispasswd_error *errl = NULL, *p;
- char xnewpass[__NPD_MAXPASSBYTES+1];
- char xnewpass2[__NPD2_MAXPASSBYTES+1];
-
- if ((clnt == (CLIENT *) NULL) ||
- (deskey == (des_block *) NULL) ||
- (newpass == NULL || *newpass == '\0')) {
- *err = NPD_INVALIDARGS;
- return (NPD_FAILED);
- }
-
- if (clnt_vers == NISPASSWD_VERS) {
- (void) memset((char *)&send_arg, 0, sizeof (send_arg));
- (void) memset((char *)&result, 0, sizeof (result));
- send_arg.ident = ident;
-
- (void) strlcpy(xnewpass, newpass, sizeof (xnewpass));
-
- if (! __npd_cbc_crypt(&randval, xnewpass, strlen(xnewpass),
- &cryptbuf1, _NPD_PASSMAXLEN, DES_ENCRYPT, deskey)) {
- *err = NPD_ENCRYPTFAIL;
- return (NPD_FAILED);
- }
- tmp_xrval = cryptbuf1.npd_xrandval;
- cryptbuf1.npd_xrandval = htonl(tmp_xrval);
- send_arg.xnewpass = cryptbuf1;
-
- /* gecos */
- send_arg.pass_info.pw_gecos = gecos;
-
- /* shell */
- send_arg.pass_info.pw_shell = shell;
-
- if (clnt_call(clnt, NISPASSWD_UPDATE,
- (xdrproc_t)xdr_npd_update, (caddr_t)&send_arg,
- (xdrproc_t)xdr_nispasswd_updresult, (caddr_t)&result,
- TIMEOUT) != RPC_SUCCESS) {
-
- /* printed to stderr */
- (void) clnt_perror(clnt,
- "update call to rpc.nispasswdd failed");
- *err = NPD_SRVNOTRESP;
- return (NPD_FAILED);
- }
-
- } else {
- (void) memset((char *)&send_arg2, 0, sizeof (send_arg2));
- (void) memset((char *)&result, 0, sizeof (result));
- send_arg2.ident = ident;
-
- (void) strlcpy(xnewpass2, newpass, sizeof (xnewpass2));
-
- if (! __npd2_cbc_crypt(&randval, xnewpass2, strlen(xnewpass2),
- &cryptbuf2, sizeof (cryptbuf2), DES_ENCRYPT,
- deskey)) {
- *err = NPD_ENCRYPTFAIL;
- return (NPD_FAILED);
- }
- tmp_xrval = cryptbuf2.npd_xrandval;
- tmp_npd_pad = cryptbuf2.npd_pad;
- cryptbuf2.npd_xrandval = htonl(tmp_xrval);
- cryptbuf2.npd_pad = htonl(tmp_npd_pad);
-
- send_arg2.xnewpass = cryptbuf2;
- /* gecos */
- send_arg2.pass_info.pw_gecos = gecos;
- /* shell */
- send_arg2.pass_info.pw_shell = shell;
-
- if (clnt_call(clnt, NISPASSWD_UPDATE,
- (xdrproc_t)xdr_npd_update2, (caddr_t)&send_arg2,
- (xdrproc_t)xdr_nispasswd_updresult, (caddr_t)&result,
- TIMEOUT) != RPC_SUCCESS) {
-
- /* printed to stderr */
- (void) clnt_perror(clnt,
- "update call to rpc.nispasswdd failed");
- *err = NPD_SRVNOTRESP;
- return (NPD_FAILED);
- }
- }
- switch (result.status) {
- case NPD_SUCCESS:
- return (NPD_SUCCESS);
- case NPD_PARTIALSUCCESS:
- /* need to assign field/err code */
- errl = &result.nispasswd_updresult_u.reason;
- if (errl == (struct nispasswd_error *)NULL) {
- *err = NPD_SYSTEMERR;
- return (NPD_FAILED);
- }
- *errlst = (nispasswd_error *)
- calloc(1, sizeof (nispasswd_error));
- if (*errlst == (struct nispasswd_error *)NULL) {
- *err = NPD_SYSTEMERR;
- return (NPD_FAILED);
- }
-
- for (p = *errlst; errl != NULL; errl = errl->next) {
- p->npd_field = errl->npd_field;
- p->npd_code = errl->npd_code;
- if (errl->next != NULL) {
- p->next = (nispasswd_error *)
- calloc(1, sizeof (nispasswd_error));
- p = p->next;
- } else
- p->next = (nispasswd_error *) NULL;
- }
- return (NPD_PARTIALSUCCESS);
- case NPD_FAILED:
- *err = result.nispasswd_updresult_u.npd_err;
- return (NPD_FAILED);
- default:
- /*
- * should never reach this case !
- */
- *err = NPD_SYSTEMERR;
- return (NPD_FAILED);
- }
-}
-
-void
-__npd_free_errlist(list)
-nispasswd_error *list;
-{
- nispasswd_error *p;
-
- if (list == NULL)
- return;
- for (; list != NULL; list = p) {
- p = list->next;
- free(list);
- }
- list = NULL;
-}
diff --git a/usr/src/lib/passwdutil/npd_clnt.h b/usr/src/lib/passwdutil/npd_clnt.h
deleted file mode 100644
index b0263ebf2e..0000000000
--- a/usr/src/lib/passwdutil/npd_clnt.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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
- * or http://www.opensolaris.org/os/licensing.
- * 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) 2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _NPD_CLNT_H
-#define _NPD_CLNT_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-nispasswd_status nispasswd_auth(char *, char *, char *, uchar_t *, char *,
- keylen_t, algtype_t, des_block *, CLIENT *, uint32_t *, uint32_t *, int *);
-
-int nispasswd_pass(CLIENT *, uint32_t, uint32_t, des_block *, char *, char *,
- char *, int *, nispasswd_error **);
-
-bool_t npd_makeclnthandle(char *, CLIENT **, char **, keylen_t *, algtype_t *,
- char **);
-
-void __npd_free_errlist(nispasswd_error *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NPD_CLNT_H */
diff --git a/usr/src/lib/passwdutil/nss_attr.c b/usr/src/lib/passwdutil/nss_attr.c
index cba482e8f3..ad8e8d46e1 100644
--- a/usr/src/lib/passwdutil/nss_attr.c
+++ b/usr/src/lib/passwdutil/nss_attr.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
@@ -190,8 +188,6 @@ nss_getpwnam(char *name, attrlist *items, pwu_repository_t *rep, void **buf)
if (private_getpwnam_r(name, &pwd, pwd_scratch,
PWD_SCRATCH_SIZE) != NULL)
pwbuf->rep_name = "files";
- else if (repositories & REP_COMPAT_NISPLUS)
- pwbuf->rep_name = "nisplus";
else if (repositories & REP_COMPAT_LDAP)
pwbuf->rep_name = "ldap";
else if (repositories & REP_COMPAT_NIS)
diff --git a/usr/src/lib/passwdutil/passwdutil.h b/usr/src/lib/passwdutil/passwdutil.h
index 7634fce552..77c8249074 100644
--- a/usr/src/lib/passwdutil/passwdutil.h
+++ b/usr/src/lib/passwdutil/passwdutil.h
@@ -100,47 +100,39 @@ typedef struct {
#define REP_NOREP 0 /* Can't find suitable repository */
#define REP_FILES 0x0001 /* /etc/passwd, /etc/shadow */
#define REP_NIS 0x0002
-#define REP_NISPLUS 0x0004
-#define REP_LDAP 0x0008
-#define REP_NSS 0x0010
+#define REP_LDAP 0x0004
+#define REP_NSS 0x0008
#define REP_LAST REP_NSS
#define REP_ERANGE 0x8000 /* Unknown repository specified */
#define REP_COMPAT_NIS 0x1000
-#define REP_COMPAT_NISPLUS 0x2000
-#define REP_COMPAT_LDAP 0x4000
+#define REP_COMPAT_LDAP 0x2000
/* For the time being, these are also defined in pam_*.h */
-#undef IS_NISPLUS
#undef IS_FILES
#undef IS_NIS
#undef IS_LDAP
#define IS_FILES(r) (r.type != NULL && strcmp(r.type, "files") == 0)
#define IS_NIS(r) (r.type != NULL && strcmp(r.type, "nis") == 0)
-#define IS_NISPLUS(r) (r.type != NULL && strcmp(r.type, "nisplus") == 0)
#define IS_LDAP(r) (r.type != NULL && strcmp(r.type, "ldap") == 0)
#define MINWEEKS -1
#define MAXWEEKS -1
#define WARNWEEKS -1
-#define NISPLUS_LOOKUP 0
-#define NISPLUS_UPDATE 1
-
typedef struct repops {
int (*checkhistory)(char *, char *, pwu_repository_t *);
int (*getattr)(char *, attrlist *, pwu_repository_t *);
int (*getpwnam)(char *, attrlist *, pwu_repository_t *, void **);
int (*update)(attrlist *, pwu_repository_t *, void *);
- int (*putpwnam)(char *, char *, char *, pwu_repository_t *, void *);
+ int (*putpwnam)(char *, char *, pwu_repository_t *, void *);
int (*user_to_authenticate)(char *, pwu_repository_t *, char **, int *);
int (*lock)(void);
int (*unlock)(void);
} repops_t;
-extern repops_t files_repops, nis_repops,
- nisplus_repops, ldap_repops, nss_repops;
+extern repops_t files_repops, nis_repops, ldap_repops, nss_repops;
extern repops_t *rops[];
@@ -171,8 +163,7 @@ int name_to_int(char *);
/*
* __set_authtok_attr.c
*/
-int __set_authtoken_attr(char *, char *, char *, pwu_repository_t *,
- attrlist *, int *);
+int __set_authtoken_attr(char *, char *, pwu_repository_t *, attrlist *, int *);
/*
* __get_authtokenn_attr.c
*/
@@ -184,11 +175,6 @@ int __get_authtoken_attr(char *, pwu_repository_t *, attrlist *);
int __user_to_authenticate(char *, pwu_repository_t *, char **, int *);
/*
- * __verify_rpc_passwd.c
- */
-int __verify_rpc_passwd(char *, char *, pwu_repository_t *);
-
-/*
* Password history definitions
*/
#define DEFHISTORY 0 /* default history depth */
@@ -221,25 +207,14 @@ int __rst_failed_count(char *, char *);
#define PWU_REPOSITORY_ERROR -13 /* Unknown repository specified */
#define PWU_AGING_DISABLED -14 /* Modifying min/warn while max==-1 */
-/* NISPLUS specific errors */
-
-#define PWU_RECOVERY_ERR -15 /* can't recover old auth token */
-#define PWU_CRED_UPDATE_ERR -16 /* failed to update credentials */
-#define PWU_ATTR_UPDATE_ERR -17 /* failed to update attributes */
-#define PWU_CRED_ERROR -18 /* failed to obtain user credentials */
-#define PWU_PARTIAL_SUCCESS -19 /* passwd is updated, creds are not */
-#define PWU_BAD_CREDPASS -20 /* password doesn't decrypt creds */
-#define PWU_NO_PRIV_CRED_UPDATE -21 /* priv. user can't update creds */
-#define PWU_UPDATED_SOME_CREDS -22 /* some, not all, creds were updated */
-
-/* More errors, not NISPLUS specific */
-
-#define PWU_PWD_TOO_SHORT -23 /* new passwd too short */
-#define PWU_PWD_INVALID -24 /* new passwd has invalid syntax */
-#define PWU_PWD_IN_HISTORY -25 /* new passwd in history list */
-#define PWU_CHANGE_NOT_ALLOWED -26 /* change not allowed */
-#define PWU_WITHIN_MIN_AGE -27 /* change not allowed, within min age */
-#define PWU_ACCOUNT_LOCKED -28 /* account successfully locked */
+/* More errors */
+
+#define PWU_PWD_TOO_SHORT -15 /* new passwd too short */
+#define PWU_PWD_INVALID -16 /* new passwd has invalid syntax */
+#define PWU_PWD_IN_HISTORY -17 /* new passwd in history list */
+#define PWU_CHANGE_NOT_ALLOWED -18 /* change not allowed */
+#define PWU_WITHIN_MIN_AGE -19 /* change not allowed, within min age */
+#define PWU_ACCOUNT_LOCKED -20 /* account successfully locked */
#ifdef __cplusplus
}
diff --git a/usr/src/lib/passwdutil/switch_utils.c b/usr/src/lib/passwdutil/switch_utils.c
index 8145ed360e..28cf6b6a74 100644
--- a/usr/src/lib/passwdutil/switch_utils.c
+++ b/usr/src/lib/passwdutil/switch_utils.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,9 +41,6 @@
#include "passwdutil.h"
-static struct passwd *nisplus_getpw_from_master(const char *, char *);
-static struct spwd *nisplus_getsp_from_master(const char *, char *);
-
/*
* name_to_int(rep)
*
@@ -59,8 +56,6 @@ name_to_int(char *rep_name)
result = REP_FILES;
else if (strcmp(rep_name, "nis") == 0)
result = REP_NIS;
- else if (strcmp(rep_name, "nisplus") == 0)
- result = REP_NISPLUS;
else if (strcmp(rep_name, "ldap") == 0)
result = REP_LDAP;
else if (strcmp(rep_name, "compat") == 0) {
@@ -71,10 +66,7 @@ name_to_int(char *rep_name)
if (cfg == NULL) {
result = REP_FILES | REP_NIS;
} else {
- if (strcmp(cfg->lookups->service_name, "nisplus") == 0)
- result = REP_FILES | REP_NISPLUS;
- else if (strcmp(cfg->lookups->service_name, "ldap") ==
- 0)
+ if (strcmp(cfg->lookups->service_name, "ldap") == 0)
result = REP_FILES | REP_LDAP;
else
result = REP_ERANGE;
@@ -96,9 +88,7 @@ get_compat_mode(void)
int result = REP_COMPAT_NIS;
if ((cfg = __nsw_getconfig("passwd_compat", &pserr)) != NULL) {
- if (strcmp(cfg->lookups->service_name, "nisplus") == 0)
- result = REP_COMPAT_NISPLUS;
- else if (strcmp(cfg->lookups->service_name, "ldap") == 0)
+ if (strcmp(cfg->lookups->service_name, "ldap") == 0)
result = REP_COMPAT_LDAP;
}
__nsw_freeconfig(cfg);
@@ -121,7 +111,7 @@ get_compat_mode(void)
* on WRITE access.
*
* If we detect read-access in compat mode, we augment the result
- * with one of REP_COMPAT_{NIS,NISPLUS,LDAP}. We need this in order to
+ * with one of REP_COMPAT_{NIS,LDAP}. We need this in order to
* implement ATTR_REP_NAME in nss_getpwnam.
*
* A return value of REP_NOREP indicates an error.
@@ -188,8 +178,6 @@ get_ns(pwu_repository_t *rep, int accesstype)
result |= REP_LDAP;
else if (strcmp(lkp2->service_name, "nis") == 0)
result |= REP_NIS;
- else if (strcmp(lkp2->service_name, "nisplus") == 0)
- result |= REP_NISPLUS;
else if (strcmp(lkp2->service_name, "ad") != 0)
result = REP_NSS;
/* AD is ignored */
@@ -199,8 +187,8 @@ get_ns(pwu_repository_t *rep, int accesstype)
} else if (conf->num_lookups == 3) {
/*
* Valid configurations with 3 repositories are:
- * files ad [nis | ldap | nisplus] OR
- * files [nis | ldap | nisplus] ad
+ * files ad [nis | ldap ] OR
+ * files [nis | ldap ] ad
*/
lkp2 = lkp->next;
lkp3 = lkp2->next;
@@ -217,8 +205,6 @@ get_ns(pwu_repository_t *rep, int accesstype)
result |= REP_LDAP;
else if (strcmp(lkpn->service_name, "nis") == 0)
result |= REP_NIS;
- else if (strcmp(lkpn->service_name, "nisplus") == 0)
- result |= REP_NISPLUS;
else
result = REP_NSS;
} else {
@@ -273,27 +259,6 @@ nss_nis_shadow(p)
}
#endif /* PAM_NIS */
-
-static void
-nss_nisplus_passwd(p)
- nss_db_params_t *p;
-{
- p->name = NSS_DBNAM_PASSWD;
- p->flags |= NSS_USE_DEFAULT_CONFIG;
- p->default_config = "nisplus";
-}
-
-static void
-nss_nisplus_shadow(p)
- nss_db_params_t *p;
-{
- p->name = NSS_DBNAM_SHADOW;
- p->config_name = NSS_DBNAM_PASSWD; /* Use config for "passwd" */
- p->flags |= NSS_USE_DEFAULT_CONFIG;
- p->default_config = "nisplus";
-}
-
-
static char *
gettok(nextpp)
char **nextpp;
@@ -643,6 +608,7 @@ endutilpwent(void)
nss_delete(&db_root);
}
+/*ARGSUSED*/
struct passwd *
getpwnam_from(const char *name, pwu_repository_t *rep, int reptype)
{
@@ -660,13 +626,6 @@ getpwnam_from(const char *name, pwu_repository_t *rep, int reptype)
(void) nss_search(&db_root, nss_ldap_passwd,
NSS_DBOP_PASSWD_BYNAME, &arg);
break;
- case REP_NISPLUS:
- if (rep && rep->scope)
- return (nisplus_getpw_from_master(name, rep->scope));
-
- (void) nss_search(&db_root, nss_nisplus_passwd,
- NSS_DBOP_PASSWD_BYNAME, &arg);
- break;
#ifdef PAM_NIS
case REP_NIS:
(void) nss_search(&db_root, nss_nis_passwd,
@@ -698,10 +657,6 @@ getpwuid_from(uid_t uid, pwu_repository_t *rep, int reptype)
(void) nss_search(&db_root, nss_ldap_passwd,
NSS_DBOP_PASSWD_BYUID, &arg);
break;
- case REP_NISPLUS:
- (void) nss_search(&db_root, nss_nisplus_passwd,
- NSS_DBOP_PASSWD_BYUID, &arg);
- break;
#ifdef PAM_NIS
case REP_NIS:
(void) nss_search(&db_root, nss_nis_passwd,
@@ -730,6 +685,7 @@ endutilspent(void)
nss_delete(&spdb_root);
}
+/*ARGSUSED*/
struct spwd *
getspnam_from(const char *name, pwu_repository_t *rep, int reptype)
{
@@ -746,13 +702,6 @@ getspnam_from(const char *name, pwu_repository_t *rep, int reptype)
(void) nss_search(&spdb_root, nss_ldap_shadow,
NSS_DBOP_SHADOW_BYNAME, &arg);
break;
- case REP_NISPLUS:
- if (rep && rep->scope)
- return (nisplus_getsp_from_master(name, rep->scope));
-
- (void) nss_search(&spdb_root, nss_nisplus_shadow,
- NSS_DBOP_SHADOW_BYNAME, &arg);
- break;
#ifdef PAM_NIS
case REP_NIS:
(void) nss_search(&spdb_root, nss_nis_shadow,
@@ -764,265 +713,3 @@ getspnam_from(const char *name, pwu_repository_t *rep, int reptype)
}
return (struct spwd *)NSS_XbyY_FINI(&arg);
}
-
-
-static nis_result *
-nisplus_match(const char *name, char *domain, char *buf, int len)
-{
- int n;
- int flags;
- nis_result *res;
- nis_object *object;
-
- n = snprintf(buf, len, "[name=%s],passwd.org_dir.%s", name, domain);
- if (n >= len) {
- syslog(LOG_ERR, "nisplus_match: name too long");
- return (NULL);
- }
- if (buf[n-1] != '.') {
- if (n == len-1) {
- syslog(LOG_ERR, "nisplus_match: name too long");
- return (NULL);
- }
- buf[n++] = '.';
- buf[n] = '\0';
- }
-
- flags = USE_DGRAM | FOLLOW_LINKS | FOLLOW_PATH | MASTER_ONLY;
-
- res = nis_list(buf, flags, NULL, NULL);
-
- if (res == NULL) {
- syslog(LOG_ERR, "nisplus_match: nis_list returned NULL");
- return (NULL);
- }
-
- if (NIS_RES_STATUS(res) != NIS_SUCCESS || NIS_RES_NUMOBJ(res) != 1) {
- syslog(LOG_ERR, "nisplus_match: match failed: %s",
- nis_sperrno(NIS_RES_STATUS(res)));
- nis_freeresult(res);
- return (NULL);
- }
-
- object = NIS_RES_OBJECT(res);
-
- if (object->EN_data.en_cols.en_cols_len < 8) {
- syslog(LOG_ERR, "nisplus_match: "
- "not a valid passwd table entry for user %s", name);
- nis_freeresult(res);
- return (NULL);
- }
-
- return (res);
-}
-
-#define SAFE_STRDUP(dst, idx) \
- if ((idx) <= 3 && ENTRY_VAL(nret, (idx)) == NULL) { \
- syslog(LOG_ERR, \
- "passwdutil: missing field from password entry"); \
- goto error; \
- } \
- len = ENTRY_LEN(nret, (idx)); \
- (dst) = malloc(len+1); \
- if ((dst) == NULL) { \
- syslog(LOG_ERR, "passwdutil: out of memory"); \
- goto error; \
- } \
- (dst)[len] = '\0'; \
- (void) strncpy((dst), \
- ENTRY_VAL(nret, (idx)) ? ENTRY_VAL(nret, (idx)) : "", \
- len);
-
-
-
-static struct passwd *
-nisplus_getpw_from_master(const char *name, char *domain)
-{
- char lookup[NIS_MAXNAMELEN+1];
- nis_result *res;
- nis_object *nret;
- int len;
- char *p;
- struct passwd *pw;
-
- if ((pw = calloc(1, sizeof (*pw))) == NULL)
- return (NULL);
-
- res = nisplus_match(name, domain, lookup, sizeof (lookup));
-
- if (res == NULL)
- return (NULL);
-
- nret = NIS_RES_OBJECT(res);
-
- SAFE_STRDUP(pw->pw_name, 0);
-
- if ((pw->pw_passwd = strdup("x")) == NULL) {
- syslog(LOG_ERR, "passwdutil: out of memory");
- goto error;
- }
-
- SAFE_STRDUP(p, 2);
- pw->pw_uid = atoi(p);
- free(p);
-
- SAFE_STRDUP(p, 3);
- pw->pw_gid = atoi(p);
- free(p);
-
- pw->pw_age = NULL;
- pw->pw_comment = NULL;
-
-/*CONSTANTCONDITION*/
- SAFE_STRDUP(pw->pw_gecos, 4);
-
-/*CONSTANTCONDITION*/
- SAFE_STRDUP(pw->pw_dir, 5);
-
-/*CONSTANTCONDITION*/
- SAFE_STRDUP(pw->pw_shell, 6);
-
- nis_freeresult(res);
-
- return (pw);
-
-error:
- nis_freeresult(res);
- if (pw->pw_name)
- free(pw->pw_name);
- if (pw->pw_passwd)
- free(pw->pw_passwd);
- if (pw->pw_gecos)
- free(pw->pw_gecos);
- if (pw->pw_dir)
- free(pw->pw_dir);
- if (pw->pw_shell)
- free(pw->pw_shell);
- free(pw);
-
- return (NULL);
-}
-
-/*
- * struct spwd * nisplus_getsp_from_master()
- *
- * Get the shadow structure from a NIS+ master.
- * This routine normally runs with EUID==0. This can cause trouble
- * if the NIS+ tables are locked down so that only the owner can
- * access the encrypted password. If we detect that scenario, we switch
- * EUID to the owner of the record and refetch it.
- */
-static struct spwd *
-nisplus_getsp_from_master(const char *name, char *domain)
-{
- char lookup[NIS_MAXNAMELEN+1];
- nis_result *res = NULL;
- nis_object *nret = NULL;
- int len;
- struct spwd *spw;
- char *shadow = NULL;
- const char *p = NULL;
- const char *limit;
-
- res = nisplus_match(name, domain, lookup, sizeof (lookup));
- if (res == NULL)
- return (NULL);
-
- nret = NIS_RES_OBJECT(res);
-
- /*CONSTANTCONDITION*/
- SAFE_STRDUP(shadow, 7);
-
- /*
- * If we got NOPWDRTR as password, try again with EUID set
- * to the UID of the record-owner.
- */
- if (strncmp(shadow, NOPWDRTR, 4) == 0) {
- char *p;
- uid_t owner_uid;
- uid_t euid = geteuid();
-
- SAFE_STRDUP(p, 2); /* record-owner field */
- owner_uid = atoi(p);
- free(p);
-
- if (owner_uid != euid) {
- /* re-obtain entry using owners EUID */
- free(shadow);
- nis_freeresult(res);
-
- (void) seteuid(owner_uid);
- res = nisplus_match(name, domain, lookup,
- sizeof (lookup));
- (void) seteuid(euid);
-
- if (res == NULL)
- return (NULL);
- nret = NIS_RES_OBJECT(res);
-
- /*CONSTANTCONDITION*/
- SAFE_STRDUP(shadow, 7);
- }
- }
-
- if ((spw = calloc(1, sizeof (*spw))) == NULL) {
- nis_freeresult(res);
- return (NULL);
- }
-
- SAFE_STRDUP(spw->sp_namp, 0);
- SAFE_STRDUP(spw->sp_pwdp, 1);
-
- nis_freeresult(res);
-
- limit = shadow + strlen(shadow) + 1;
- p = shadow;
-
- spw->sp_lstchg = -1;
- spw->sp_min = -1;
- spw->sp_max = -1;
- spw->sp_warn = -1;
- spw->sp_inact = -1;
- spw->sp_expire = -1;
- spw->sp_flag = 0;
-
- if (!getfield(&p, limit, 0, &spw->sp_lstchg))
- goto out;
-
- if (!getfield(&p, limit, 0, &spw->sp_min))
- goto out;
-
- if (!getfield(&p, limit, 0, &spw->sp_max))
- goto out;
-
- if (!getfield(&p, limit, 0, &spw->sp_warn))
- goto out;
-
- if (!getfield(&p, limit, 0, &spw->sp_inact))
- goto out;
-
- if (!getfield(&p, limit, 0, &spw->sp_expire))
- goto out;
-
- if (!getfield(&p, limit, 1, &spw->sp_flag))
- goto out;
-
- if (p != limit) {
- syslog(LOG_ERR, "passwdutil: garbage at end of record");
- goto error;
- }
-
-out:
- free(shadow);
- return (spw);
-
-error:
- if (spw->sp_namp)
- free(spw->sp_namp);
- if (spw->sp_pwdp)
- free(spw->sp_pwdp);
- free(spw);
- if (shadow)
- free(shadow);
- return (NULL);
-}
diff --git a/usr/src/lib/passwdutil/utils.c b/usr/src/lib/passwdutil/utils.c
index 2f6474ef29..01691ed5d4 100644
--- a/usr/src/lib/passwdutil/utils.c
+++ b/usr/src/lib/passwdutil/utils.c
@@ -43,26 +43,17 @@
#define MAXWEEKS -1
#define WARNWEEKS -1
-extern repops_t files_repops, nis_repops,
- nisplus_repops, ldap_repops, nss_repops;
+extern repops_t files_repops, nis_repops, ldap_repops, nss_repops;
repops_t *rops[REP_LAST+1] = {
NULL,
&files_repops,
&nis_repops,
NULL,
- &nisplus_repops,
- NULL,
- NULL,
- NULL,
&ldap_repops,
NULL,
NULL,
NULL,
- NULL,
- NULL,
- NULL,
- NULL,
&nss_repops,
};