diff options
author | Raja Andra <Rajagopal.Andra@Sun.COM> | 2009-12-06 01:39:21 -0800 |
---|---|---|
committer | Raja Andra <Rajagopal.Andra@Sun.COM> | 2009-12-06 01:39:21 -0800 |
commit | 36e852a172cba914383d7341c988128b2c667fbd (patch) | |
tree | 6cf9fe61b54ffa5f49f74f8b3ee20249279d5efe /usr/src/lib/passwdutil | |
parent | 560e0ee2bb5791b5efe2cbdc74d0a76f06dbd84d (diff) | |
download | illumos-joyent-36e852a172cba914383d7341c988128b2c667fbd.tar.gz |
6874309 Remove NIS+ from Solaris
Diffstat (limited to 'usr/src/lib/passwdutil')
-rw-r--r-- | usr/src/lib/passwdutil/Makefile.com | 23 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/__failed_count.c | 4 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/__set_authtoken_attr.c | 16 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/__verify_rpc_passwd.c | 68 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/files_attr.c | 11 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/ldap_attr.c | 10 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/mapfile-vers | 1 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/nis_attr.c | 40 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/nisplus_attr.c | 1483 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/npd_clnt.c | 567 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/npd_clnt.h | 51 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/nss_attr.c | 6 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/passwdutil.h | 53 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/switch_utils.c | 329 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/utils.c | 11 |
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, }; |