Mercurial > illumos > illumos-gate
changeset 10008:b5d6e292a984
PSARC 2008/295 NISPASSWD_VERS2
6563443 nisaddcred and chkey have issues in md5 password encyption with passwords > eight characters
author | Ashok Kumar T <Ashok.Kumar@Sun.COM> |
---|---|
date | Wed, 01 Jul 2009 22:27:19 +0530 |
parents | 1b2a9b424228 |
children | 11b987df0f95 |
files | usr/src/cmd/keyserv/chkey.c usr/src/cmd/keyserv/newkey.c usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svc.c usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svcsubr.h usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/rpc.nispasswdd.c usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedescred.c usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedhextcred.c usr/src/head/rpcsvc/nispasswd.x usr/src/lib/libnsl/common/llib-lnsl usr/src/lib/libnsl/common/mapfile-vers usr/src/lib/libnsl/nis/gen/npd_lib.c usr/src/lib/passwdutil/nisplus_attr.c usr/src/lib/passwdutil/npd_clnt.c |
diffstat | 13 files changed, 929 insertions(+), 475 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/keyserv/chkey.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/cmd/keyserv/chkey.c Wed Jul 01 22:27:19 2009 +0530 @@ -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. */ @@ -49,6 +49,7 @@ #include <rpc/rpc.h> #include <rpc/key_prot.h> #include <rpcsvc/nis.h> +#include <rpcsvc/nispasswd.h> #include <rpcsvc/nis_dhext.h> #include <rpcsvc/ypclnt.h> #include <nsswitch.h> @@ -96,6 +97,8 @@ char **rpc_pws = NULL; /* List of S-RPC passwords */ int rpc_pw_count = 0; /* Number of passwords entered by user */ char *login_pw = NULL; /* Unencrypted login password */ +char short_login_pw[DESCREDPASSLEN + 1]; +/* Short S-RPC password, which has first 8 chars of login_pw */ static int add_cred_obj(nis_object *, char *); static nis_error auth_exists(char *, char *, char *, char *); @@ -153,7 +156,7 @@ usage() { fprintf(stderr, "usage: %s [-p] [-s ldap | nisplus | nis | files] \n", - program_name); + program_name); exit(1); } @@ -169,8 +172,8 @@ char *crypt = NULL; if (!xencrypt_g(slist[mcount], CURMECH->keylen, - CURMECH->algtype, login_pw, netname, - &crypt, TRUE)) { + CURMECH->algtype, short_login_pw, netname, + &crypt, TRUE)) { /* Could not crypt key */ crypt = NULL; } else @@ -181,15 +184,15 @@ char *crypt = NULL; if (!(crypt = - (char *)malloc(HEXKEYBYTES + KEYCHECKSUMSIZE + 1))) { + (char *)malloc(HEXKEYBYTES + KEYCHECKSUMSIZE + 1))) { fprintf(stderr, "%s: Malloc failure.\n", program_name); exit(1); } - memcpy(crypt, slist[0], HEXKEYBYTES); - memcpy(crypt + HEXKEYBYTES, slist[0], KEYCHECKSUMSIZE); + (void) memcpy(crypt, slist[0], HEXKEYBYTES); + (void) memcpy(crypt + HEXKEYBYTES, slist[0], KEYCHECKSUMSIZE); crypt[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; - xencrypt(crypt, login_pw); + xencrypt(crypt, short_login_pw); clist[0] = crypt; ccount++; @@ -197,7 +200,7 @@ if (!ccount) { fprintf(stderr, "%s: Could not encrypt any secret keys.\n", - program_name); + program_name); exit(1); } } @@ -211,7 +214,8 @@ if (!nomech) { assert(mechs && mechs[0]); - for (mcount = 0; CURMECH; mcount++); + for (mcount = 0; CURMECH; mcount++) + ; } else mcount = 1; @@ -245,17 +249,17 @@ hexkeylen = ((CURMECH->keylen / 8) * 2) + 1; if (!(public = (char *)malloc(hexkeylen))) { fprintf(stderr, "%s: Malloc failure.\n", - program_name); + program_name); exit(1); } if (!getpublickey_g(netname, CURMECH->keylen, - CURMECH->algtype, public, - hexkeylen)) { + CURMECH->algtype, public, + hexkeylen)) { /* Could not get public key */ fprintf(stderr, - "Could not get %s public key.\n", - VALID_ALIAS(CURMECH->alias) ? - CURMECH->alias : ""); + "Could not get %s public key.\n", + VALID_ALIAS(CURMECH->alias) ? + CURMECH->alias : ""); free(public); public = NULL; } else @@ -281,11 +285,11 @@ if (!pcount) { fprintf(stderr, "%s: cannot get any public keys for %s.\n", - program_name, pw->pw_name); + program_name, pw->pw_name); error_msg(); fprintf(stderr, "Make sure that the public keys are stored in the domain %s.\n", - local_domain); + local_domain); exit(1); } } @@ -309,22 +313,22 @@ if (!(public = malloc(hexkeylen))) { fprintf(stderr, "%s: Malloc failure.\n", - program_name); + program_name); exit(1); } if (!(secret = malloc(hexkeylen))) { fprintf(stderr, "%s: Malloc failure.\n", - program_name); + program_name); exit(1); } if (!(__gen_dhkeys_g(public, secret, CURMECH->keylen, - CURMECH->algtype, login_pw))) { + CURMECH->algtype, short_login_pw))) { /* Could not generate key pair */ fprintf(stderr, "WARNING Could not generate key pair %s\n", - VALID_ALIAS(CURMECH->alias) ? - CURMECH->alias : ""); + VALID_ALIAS(CURMECH->alias) ? + CURMECH->alias : ""); free(public); free(secret); public = NULL; @@ -348,7 +352,7 @@ exit(1); } - __gen_dhkeys(public, secret, login_pw); + __gen_dhkeys(public, secret, short_login_pw); plist[0] = public; slist[0] = secret; @@ -366,19 +370,25 @@ char baseprompt[] = "Please enter the login password for"; char prompt[BUFSIZ]; char *en_login_pw = spw->sp_pwdp; + char short_en_login_pw[DESCREDPASSLEN + 1]; char *try_en_login_pw; bool_t pwmatch = FALSE; int done = 0, tries = 0, pcount; snprintf(prompt, BUFSIZ, "%s %s:", baseprompt, pw->pw_name); + (void) strlcpy(short_en_login_pw, en_login_pw, + sizeof (short_en_login_pw)); + if (en_login_pw && (strlen(en_login_pw) != 0)) { for (pcount = 0; pcount < rpc_pw_count; pcount++) { char *try_en_rpc_pw; - try_en_rpc_pw = crypt(rpc_pws[pcount], en_login_pw); - if (strcmp(try_en_rpc_pw, en_login_pw) == 0) { + try_en_rpc_pw = crypt(rpc_pws[pcount], short_en_login_pw); + if (strcmp(try_en_rpc_pw, short_en_login_pw) == 0) { login_pw = rpc_pws[pcount]; + (void) strlcpy(short_login_pw, login_pw, + sizeof (short_login_pw)); pwmatch = TRUE; break; } @@ -387,14 +397,16 @@ /* pw don't match */ while (!done) { /* ask for the pw */ - login_pw = getpass(prompt); + login_pw = getpassphrase(prompt); + (void) strlcpy(short_login_pw, login_pw, + sizeof (short_login_pw)); if (login_pw && strlen(login_pw)) { /* pw was not empty */ try_en_login_pw = crypt(login_pw, - en_login_pw); + en_login_pw); /* compare the pw's */ if (!(strcmp(try_en_login_pw, - en_login_pw))) { + en_login_pw))) { /* pw was correct */ return; } else { @@ -402,15 +414,15 @@ if (tries++) { /* Sorry */ fprintf(stderr, - "Sorry.\n"); + "Sorry.\n"); exit(1); } else { /* Try again */ snprintf(prompt, - BUFSIZ, + BUFSIZ, "Try again. %s %s:", - baseprompt, - pw->pw_name); + baseprompt, + pw->pw_name); } } } else { @@ -419,15 +431,15 @@ /* Unchanged */ fprintf(stderr, "%s: key-pair(s) unchanged for %s.\n", - program_name, - pw->pw_name); + program_name, + pw->pw_name); exit(1); } else { /* Need a password */ snprintf(prompt, BUFSIZ, "Need a password. %s %s:", - baseprompt, - pw->pw_name); + baseprompt, + pw->pw_name); } } } @@ -438,7 +450,7 @@ /* no pw found */ fprintf(stderr, "%s: no passwd found for %s in the shadow passwd entry.\n", - program_name, pw->pw_name); + program_name, pw->pw_name); exit(1); } } @@ -453,24 +465,24 @@ if (flavor) snprintf(prompt, BUFSIZ, - "Please enter the %s Secure-RPC password for %s:", - flavor, pw->pw_name); + "Please enter the %s Secure-RPC password for %s:", + flavor, pw->pw_name); else snprintf(prompt, BUFSIZ, - "Please enter the Secure-RPC password for %s:", - pw->pw_name); + "Please enter the Secure-RPC password for %s:", + pw->pw_name); cur_pw = getpass(prompt); if (!cur_pw) { /* No changes */ fprintf(stderr, "%s: key-pair(s) unchanged for %s.\n", - program_name, pw->pw_name); + program_name, pw->pw_name); exit(1); } rpc_pw_count++; if (!(rpc_pws = - (char **)realloc(rpc_pws, sizeof (char *) * rpc_pw_count))) { + (char **)realloc(rpc_pws, sizeof (char *) * rpc_pw_count))) { fprintf(stderr, "%s: Realloc failure.\n", program_name); exit(1); } @@ -495,17 +507,17 @@ hexkeylen = ((CURMECH->keylen / 8) * 2) + 1; if (!(secret = (char *)calloc(hexkeylen, - sizeof (char)))) { + sizeof (char)))) { fprintf(stderr, "%s: Malloc failure.\n", - program_name); + program_name); exit(1); } for (pcount = 0; pcount < rpc_pw_count; pcount++) { if (!getsecretkey_g(netname, CURMECH->keylen, - CURMECH->algtype, secret, - hexkeylen, - rpc_pws[pcount])) + CURMECH->algtype, secret, + hexkeylen, + rpc_pws[pcount])) continue; if (secret[0] == 0) @@ -524,11 +536,11 @@ */ getrpcpws(CURMECH->alias); if (!getsecretkey_g(netname, - CURMECH->keylen, - CURMECH->algtype, - secret, - hexkeylen, - rpc_pws[pcount])) { + CURMECH->keylen, + CURMECH->algtype, + secret, + hexkeylen, + rpc_pws[pcount])) { /* * Could not retreive * secret key, abort @@ -551,7 +563,7 @@ } else { fprintf(stderr, "%s: key-pair unchanged for %s.\n", - program_name, pw->pw_name); + program_name, pw->pw_name); exit(1); } } else @@ -570,8 +582,8 @@ getsecrets_tryagain: if (!getsecretkey(netname, secret, rpc_pws[0])) { fprintf(stderr, - "%s: could not get secret key for '%s'\n", - program_name, netname); + "%s: could not get secret key for '%s'\n", + program_name, netname); exit(1); } @@ -586,8 +598,8 @@ goto getsecrets_tryagain; } else { fprintf(stderr, - "%s: key-pair unchanged for %s.\n", - program_name, pw->pw_name); + "%s: key-pair unchanged for %s.\n", + program_name, pw->pw_name); exit(1); } } @@ -599,7 +611,7 @@ if (!scount) { (void) fprintf(stderr, "%s: could not get nor decrypt any secret keys for '%s'\n", - program_name, netname); + program_name, netname); error_msg(); exit(1); } @@ -635,7 +647,7 @@ perror("Warning: NFS credentials not destroyed"); #endif /* NFS_AUTH */ - memcpy(netst.st_priv_key, secret, HEXKEYBYTES); + (void) memcpy(netst.st_priv_key, secret, HEXKEYBYTES); netst.st_pub_key[0] = '\0'; netst.st_netname = strdup(netname); @@ -659,15 +671,15 @@ if (keylen == CURMECH->keylen && algtype == CURMECH->algtype) { if (key_setnet_g(netname, slist[mcount], - CURMECH->keylen, - NULL, 0, - CURMECH->algtype) + CURMECH->keylen, + NULL, 0, + CURMECH->algtype) < 0) fprintf(stderr, "Could not set %s's %s secret key\n", - netname, - VALID_ALIAS(CURMECH->alias) ? - CURMECH->alias : ""); + netname, + VALID_ALIAS(CURMECH->alias) ? + CURMECH->alias : ""); } } } else { @@ -749,14 +761,14 @@ if ((rootfd = open(ROOTKEY_FILE, O_WRONLY+O_CREAT, 0600)) < 0) { perror("Could not open /etc/.rootkey for writing"); fprintf(stderr, - "Attempting to restore original /etc/.rootkey\n"); + "Attempting to restore original /etc/.rootkey\n"); rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); goto rootkey_err; } if (!(rootfile = fdopen(rootfd, "w"))) { perror("Could not open /etc/.rootkey for writing"); fprintf(stderr, - "Attempting to restore original /etc/.rootkey\n"); + "Attempting to restore original /etc/.rootkey\n"); close(rootfd); unlink(ROOTKEY_FILE); rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); @@ -765,7 +777,7 @@ if (!(bakfile = fopen(ROOTKEY_FILE_BACKUP, "r"))) { perror("Could not open /etc/.rootkey.bak for reading"); fprintf(stderr, - "Attempting to restore original /etc/.rootkey\n"); + "Attempting to restore original /etc/.rootkey\n"); fclose(rootfile); unlink(ROOTKEY_FILE); rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); @@ -830,7 +842,7 @@ rootkey_err: fprintf(stderr, "WARNING: Could not write %s key to /etc/.rootkey\n", - flavor); + flavor); } @@ -846,7 +858,7 @@ if (nis_princ == NULL) { (void) fprintf(stderr, "%s: you must create a \"LOCAL\" credential for '%s' first.\n", - program_name, netname); + program_name, netname); (void) fprintf(stderr, "\tSee nisaddcred(1).\n"); return (0); } @@ -856,15 +868,15 @@ if (nis_princ[len-1] != '.') { (void) fprintf(stderr, "%s: invalid principal name: '%s' (forgot ending dot?).\n", - program_name, nis_princ); + program_name, nis_princ); return (0); } /* Sanity check 1. We only deal with one type of netnames. */ if (strncmp(netname, "unix", 4) != 0) { (void) fprintf(stderr, - "%s: unrecognized netname type: '%s'.\n", - program_name, netname); + "%s: unrecognized netname type: '%s'.\n", + program_name, netname); return (0); } @@ -873,7 +885,7 @@ if (strcasecmp(princdomain, domain) != 0) { (void) fprintf(stderr, "%s: domain of principal '%s' does not match destination domain '%s'.\n", - program_name, nis_princ, domain); + program_name, nis_princ, domain); (void) fprintf(stderr, "Should only add DES credential of principal in its home domain\n"); return (0); @@ -886,7 +898,7 @@ netdomain = (char *)strchr(netname, '@'); if (! netdomain || netname[strlen(netname)-1] == '.') { (void) fprintf(stderr, "%s: invalid netname: '%s'. \n", - program_name, netname); + program_name, netname); return (0); } netdomain++; /* skip '@' */ @@ -894,7 +906,7 @@ if (strlcpy(netdomainaux, netdomain, sizeof (netdomainaux)) >= sizeof (netdomainaux)) { (void) fprintf(stderr, "%s: net domain name %s is too long\n", - program_name, netdomain); + program_name, netdomain); return (0); } @@ -902,8 +914,8 @@ if (strlcat(netdomainaux, ".", sizeof (netdomainaux)) >= sizeof (netdomainaux)) { (void) fprintf(stderr, - "%s: net domain name %s is too long\n", - program_name, netdomainaux); + "%s: net domain name %s is too long\n", + program_name, netdomainaux); return (0); } } @@ -911,7 +923,7 @@ if (strcasecmp(princdomain, netdomainaux) != 0) { (void) fprintf(stderr, "%s: domain of netname %s should be same as that of principal %s\n", - program_name, netname, nis_princ); + program_name, netname, nis_princ); return (0); } @@ -937,31 +949,31 @@ break; case PK_NISPLUS: nis_princ = get_nisplus_principal(nis_local_directory(), - geteuid()); + geteuid()); break; case PK_YP: yp_get_default_domain(&ypdomain); if (yp_master(ypdomain, PKMAP, &ypmaster) != 0) { fprintf(stderr, "%s: cannot find master of NIS publickey database\n", - program_name); + program_name); exit(1); } fprintf(stdout, - "Sending key change request to %s ...\n", ypmaster); + "Sending key change request to %s ...\n", ypmaster); break; case PK_FILES: if (geteuid() != 0) { fprintf(stderr, "%s: non-root users cannot change their key-pair in %s\n", - program_name, PKFILE); + program_name, PKFILE); exit(1); } break; default: fprintf(stderr, - "could not update; database %d unknown\n", - dest_service); + "could not update; database %d unknown\n", + dest_service); exit(1); } @@ -973,38 +985,38 @@ continue; __nis_mechalias2authtype(CURMECH->alias, authtype, - MECH_MAXATNAME); + MECH_MAXATNAME); if (!authtype) { fprintf(stderr, "Could not generate auth_type for %s.\n", - CURMECH->alias); + CURMECH->alias); continue; } snprintf(pkent, MAXPKENTLEN, "%s:%s:%d", - plist[mcount], clist[mcount], - CURMECH->algtype); + plist[mcount], clist[mcount], + CURMECH->algtype); switch (dest_service) { case PK_LDAP: if (ldap_update(CURMECH->alias, netname, - plist[mcount], clist[mcount], - login_pw)) + plist[mcount], clist[mcount], + login_pw)) fprintf(stderr, "%s: unable to update %s key in LDAP database\n", - program_name, authtype); + program_name, authtype); else ucount++; break; case PK_NISPLUS: if (nisplus_update(nis_princ, - authtype, - plist[mcount], - clist[mcount])) + authtype, + plist[mcount], + clist[mcount])) fprintf(stderr, "%s: unable to update %s key in nisplus database\n", - program_name, authtype); + program_name, authtype); else ucount++; break; @@ -1027,11 +1039,11 @@ switch (dest_service) { case PK_LDAP: if (ldap_update("dh192-0", netname, - plist[0], clist[0], - login_pw)) { + plist[0], clist[0], + login_pw)) { fprintf(stderr, "%s: unable to update %s key in LDAP database\n", - program_name); + program_name); exit(1); } break; @@ -1039,25 +1051,25 @@ case PK_NISPLUS: assert(plist[0] && clist[0]); if (nisplus_update(nis_princ, - AUTH_DES_AUTH_TYPE, - plist[0], - clist[0])) { - fprintf(stderr, + AUTH_DES_AUTH_TYPE, + plist[0], + clist[0])) { + fprintf(stderr, "%s: unable to update nisplus database\n", - program_name); + program_name); exit(1); } break; case PK_YP: if (status = yp_update(ypdomain, PKMAP, - YPOP_STORE, netname, - strlen(netname), pkent, - strlen(pkent))) { + YPOP_STORE, netname, + strlen(netname), pkent, + strlen(pkent))) { fprintf(stderr, "%s: unable to update NIS database (%u): %s\n", - program_name, status, - yperr_string(status)); + program_name, status, + yperr_string(status)); exit(1); } break; @@ -1066,7 +1078,7 @@ if (localupdate(netname, PKFILE, YPOP_STORE, pkent)) { fprintf(stderr, "%s: hence, unable to update publickey database\n", - program_name); + program_name); exit(1); } break; @@ -1079,7 +1091,7 @@ } if (!ucount) { fprintf(stderr, "%s: unable to update any key-pairs for %s.\n", - program_name, pw->pw_name); + program_name, pw->pw_name); exit(1); } } @@ -1095,13 +1107,13 @@ char *foundprinc; (void) sprintf(sname, "[auth_name=%s,auth_type=%s],%s.%s", - auth_name, auth_type, CRED_TABLE, domain); + auth_name, auth_type, CRED_TABLE, domain); if (sname[strlen(sname)-1] != '.') strcat(sname, "."); /* Don't want FOLLOW_PATH here */ res = nis_list(sname, - MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, - NULL, NULL); + MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, + NULL, NULL); status = res->status; switch (res->status) { @@ -1109,14 +1121,14 @@ break; case NIS_TRYAGAIN: (void) fprintf(stderr, - "%s: NIS+ server busy, try again later.\n", - program_name); + "%s: NIS+ server busy, try again later.\n", + program_name); exit(1); break; case NIS_PERMISSION: (void) fprintf(stderr, "%s: insufficient permission to look up old credentials.\n", - program_name); + program_name); exit(1); break; case NIS_SUCCESS: @@ -1124,14 +1136,14 @@ if (nis_dir_cmp(foundprinc, princname) != SAME_NAME) { (void) fprintf(stderr, "%s: %s credentials with auth_name '%s' already belong to '%s'.\n", - program_name, auth_type, auth_name, foundprinc); + program_name, auth_type, auth_name, foundprinc); exit(1); } break; default: (void) fprintf(stderr, - "%s: error looking at cred table, NIS+ error: %s\n", - program_name, nis_sperrno(res->status)); + "%s: error looking at cred table, NIS+ error: %s\n", + program_name, nis_sperrno(res->status)); exit(1); } nis_freeresult(res); @@ -1148,15 +1160,15 @@ nis_error status; snprintf(sname, NIS_MAXNAMELEN, - "[cname=\"%s\",auth_type=%s],%s.%s", - nisprinc, flavor, CRED_TABLE, domain); + "[cname=\"%s\",auth_type=%s],%s.%s", + nisprinc, flavor, CRED_TABLE, domain); if (sname[strlen(sname)-1] != '.') strcat(sname, "."); /* Don't want FOLLOW_PATH here */ res = nis_list(sname, - MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, - NULL, NULL); + MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, + NULL, NULL); status = res->status; switch (status) { @@ -1164,14 +1176,14 @@ break; case NIS_TRYAGAIN: fprintf(stderr, - "%s: NIS+ server busy, try again later.\n", - program_name); + "%s: NIS+ server busy, try again later.\n", + program_name); exit(1); break; case NIS_PERMISSION: (void) fprintf(stderr, "%s: insufficient permission to look at credentials table\n", - program_name); + program_name); exit(1); break; case NIS_SUCCESS: @@ -1179,8 +1191,8 @@ break; default: (void) fprintf(stderr, - "%s: error looking at cred table, NIS+ error: %s\n", - program_name, nis_sperrno(res->status)); + "%s: error looking at cred table, NIS+ error: %s\n", + program_name, nis_sperrno(res->status)); exit(1); } nis_freeresult(res); @@ -1200,14 +1212,14 @@ switch (res->status) { case NIS_TRYAGAIN: (void) fprintf(stderr, - "%s: NIS+ server busy, try again later.\n", - program_name); + "%s: NIS+ server busy, try again later.\n", + program_name); exit(1); break; case NIS_PERMISSION: (void) fprintf(stderr, - "%s: insufficient permission to update credentials.\n", - program_name); + "%s: insufficient permission to update credentials.\n", + program_name); exit(1); break; case NIS_SUCCESS: @@ -1215,8 +1227,8 @@ break; default: (void) fprintf(stderr, - "%s: error modifying credential, NIS+ error: %s.\n", - program_name, nis_sperrno(res->status)); + "%s: error modifying credential, NIS+ error: %s.\n", + program_name, nis_sperrno(res->status)); exit(1); } nis_freeresult(res); @@ -1238,14 +1250,14 @@ switch (res->status) { case NIS_TRYAGAIN: (void) fprintf(stderr, - "%s: NIS+ server busy, try again later.\n", - program_name); + "%s: NIS+ server busy, try again later.\n", + program_name); exit(1); break; case NIS_PERMISSION: (void) fprintf(stderr, - "%s: insufficient permission to update credentials.\n", - program_name); + "%s: insufficient permission to update credentials.\n", + program_name); exit(1); break; case NIS_SUCCESS: @@ -1253,8 +1265,8 @@ break; default: (void) fprintf(stderr, - "%s: error creating credential, NIS+ error: %s.\n", - program_name, nis_sperrno(res->status)); + "%s: error creating credential, NIS+ error: %s.\n", + program_name, nis_sperrno(res->status)); exit(1); } nis_freeresult(res); @@ -1274,7 +1286,7 @@ if (!(userdomain = strchr(netname, '@'))) { fprintf(stderr, "%s: invalid netname: '%s'.\n", - program_name, netname); + program_name, netname); exit(1); } userdomain++; @@ -1282,8 +1294,8 @@ if (strlcpy(cmpdomain, userdomain, sizeof (cmpdomain)) >= sizeof (cmpdomain)) { (void) fprintf(stderr, - "%s: net domain name %s is too long\n", - program_name, cmpdomain); + "%s: net domain name %s is too long\n", + program_name, cmpdomain); exit(1); } @@ -1291,8 +1303,8 @@ if (strlcat(cmpdomain, ".", sizeof (cmpdomain)) >= sizeof (cmpdomain)) { (void) fprintf(stderr, - "%s: net domain name %s is too long\n", - program_name, cmpdomain); + "%s: net domain name %s is too long\n", + program_name, cmpdomain); exit(1); } } @@ -1327,8 +1339,8 @@ obj->zo_domain = domain; /* owner: r, group: rmcd */ obj->zo_access = ((NIS_READ_ACC<<16)| - (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC| - NIS_DESTROY_ACC)<<8); + (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC| + NIS_DESTROY_ACC)<<8); status = add_cred_obj(obj, domain); } else { obj->EN_data.en_cols.en_cols_val[3].ec_flags |= EN_MODIFIED; @@ -1359,28 +1371,29 @@ */ numspecmech++; if ((mechs = - (mechanism_t **)realloc(mechs, - sizeof (mechanism_t *) * (numspecmech + 1))) == - NULL) { + (mechanism_t **)realloc(mechs, + sizeof (mechanism_t *) * + (numspecmech + 1))) == NULL) { perror("Can not change keys"); exit(1); } if ((mechs[numspecmech - 1] = - (mechanism_t *)malloc(sizeof (mechanism_t))) == NULL) { + (mechanism_t *)malloc( + sizeof (mechanism_t))) == NULL) { perror("Can not change keys"); exit(1); } if (realmechlist[i]->mechname) mechs[numspecmech - 1]->mechname = - strdup(realmechlist[i]->mechname); + strdup(realmechlist[i]->mechname); if (realmechlist[i]->alias) mechs[numspecmech - 1]->alias = - strdup(realmechlist[i]->alias); + strdup(realmechlist[i]->alias); mechs[numspecmech - 1]->keylen = - realmechlist[i]->keylen; + realmechlist[i]->keylen; mechs[numspecmech - 1]->algtype = - realmechlist[i]->algtype; + realmechlist[i]->algtype; mechs[numspecmech] = NULL; __nis_release_mechanisms(realmechlist); return; @@ -1389,13 +1402,13 @@ fprintf(stderr, "WARNING: Mechanism '%s' not configured, skipping...\n", - mechtype); + mechtype); __nis_release_mechanisms(realmechlist); return; } fprintf(stderr, - "WARNING: Mechanism '%s' not configured, skipping...\n", - mechtype); + "WARNING: Mechanism '%s' not configured, skipping...\n", + mechtype); } @@ -1452,7 +1465,7 @@ } if (!__getnetnamebyuid(netname, uid = getuid())) { fprintf(stderr, "%s: cannot generate netname for uid %d\n", - program_name, uid); + program_name, uid); exit(1); } sec_domain = strdup(strchr(netname, '@') + 1); @@ -1467,7 +1480,7 @@ if (dest_service == PK_YP || dest_service == PK_FILES) { fprintf(stderr, "%s: can not add non-DES public keys to %s, skipping.\n", - program_name, service); + program_name, service); __nis_release_mechanisms(mechs); mechs = NULL; initkeylist(TRUE); @@ -1482,8 +1495,8 @@ /* Get password information */ if ((pw = getpwuid(uid)) == NULL) { fprintf(stderr, - "%s: Can not find passwd information for %d.\n", - program_name, uid); + "%s: Can not find passwd information for %d.\n", + program_name, uid); exit(1); } @@ -1506,10 +1519,10 @@ keylogin(CURMECH->keylen, CURMECH->algtype); if ((uid == 0) && (makenew == FALSE)) write_rootkey(slist[mcount], - VALID_ALIAS(CURMECH->alias) ? - CURMECH->alias : - "", - keylen, algtype); + VALID_ALIAS(CURMECH->alias) ? + CURMECH->alias : + "", + keylen, algtype); } } } else { @@ -1544,8 +1557,8 @@ (void) seteuid(uid); (void) fprintf(stderr, - "%s: cannot find shadow entry for %s.\n", - program_name, pw->pw_name); + "%s: cannot find shadow entry for %s.\n", + program_name, pw->pw_name); exit(1); } @@ -1555,7 +1568,7 @@ if (strcmp(spw->sp_pwdp, NOPWDRTR) == 0) { (void) fprintf(stderr, "%s: do not have read access to the passwd field for %s\n", - program_name, pw->pw_name); + program_name, pw->pw_name); exit(1); } @@ -1566,10 +1579,12 @@ if (force) { char *prompt = "Please enter New password:"; - login_pw = getpass(prompt); + login_pw = getpassphrase(prompt); + (void) strlcpy(short_login_pw, login_pw, + sizeof (short_login_pw)); if (!login_pw || !(strlen(login_pw))) { fprintf(stderr, "%s: key-pair(s) unchanged for %s.\n", - program_name, pw->pw_name); + program_name, pw->pw_name); exit(1); } } else { @@ -1598,9 +1613,9 @@ if (!slist[mcount]) continue; write_rootkey(slist[mcount], - CURMECH->alias, - CURMECH->keylen, - CURMECH->algtype); + CURMECH->alias, + CURMECH->keylen, + CURMECH->algtype); } } else { assert(slist[0]); @@ -1610,7 +1625,7 @@ if (mechs) { for (mcount = 0; CURMECH; mcount++) keylogin(CURMECH->keylen, - CURMECH->algtype); + CURMECH->algtype); } else keylogin_des(); }
--- a/usr/src/cmd/keyserv/newkey.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/cmd/keyserv/newkey.c Wed Jul 01 22:27:19 2009 +0530 @@ -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,7 +19,7 @@ * 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. */ @@ -37,8 +36,6 @@ * contributors. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Administrative tool to add a new user to the publickey database */ @@ -56,6 +53,7 @@ #include <sys/resource.h> #include <netdir.h> #include <rpcsvc/nis.h> +#include <rpcsvc/nispasswd.h> #define MAXMAPNAMELEN 256 #define MAXPASSWD 256 /* max significant characters in password */ @@ -93,7 +91,8 @@ char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; int status; char *pass, *target_host = NULL, - *username = NULL, *pk_service = NULL; + *username = NULL, *pk_service = NULL; + char short_pass[DESCREDPASSLEN + 1]; struct passwd *pw; NCONF_HANDLE *nc_handle; struct netconfig *nconf; @@ -146,7 +145,7 @@ pw = getpwnam(username); if (pw == NULL) { (void) fprintf(stderr, "%s: unknown user: '%s'\n", - program_name, username); + program_name, username); exit(1); } uid = pw->pw_uid; @@ -154,17 +153,17 @@ if (! getnetname(name)) { (void) fprintf(stderr, "%s: could not get the equivalent netname for %s\n", - program_name, username); + program_name, username); usage(); } if (pk_database == PK_NISPLUS) target_host = nis_local_host(); else { if (gethostname(host_pname, NIS_MAXNAMELEN) - < 0) { + < 0) { (void) fprintf(stderr, "%s: could not get the hostname for %s\n", - program_name, username); + program_name, username); usage(); } target_host = host_pname; @@ -173,12 +172,12 @@ if (__getnetnamebyuid(name, uid) == 0) { (void) fprintf(stderr, "%s: could not get the equivalent netname for %s\n", - program_name, username); + program_name, username); usage(); } if (pk_database == PK_NISPLUS) nprinc = get_nisplus_principal(nis_local_directory(), - uid); + uid); } else { /* -h hostname option */ service.h_host = target_host; @@ -189,8 +188,8 @@ if (nc_handle == NULL) { /* fails to open netconfig file */ (void) fprintf(stderr, - "%s: failed in routine setnetconfig()\n", - program_name); + "%s: failed in routine setnetconfig()\n", + program_name); exit(2); } while (nconf = getnetconfig(nc_handle)) { @@ -205,14 +204,14 @@ endnetconfig(nc_handle); if (!validhost) { (void) fprintf(stderr, "%s: unknown host: %s\n", - program_name, target_host); + program_name, target_host); exit(1); } (void) host2netname(name, target_host, (char *)NULL); if (pk_database == PK_NISPLUS) { if (target_host[strlen(target_host) - 1] != '.') { sprintf(host_pname, "%s.%s", - target_host, nis_local_directory()); + target_host, nis_local_directory()); nprinc = host_pname; } else nprinc = target_host; @@ -226,36 +225,37 @@ if (pass == NULL) exit(1); - (void) __gen_dhkeys(public, secret, pass); + (void) strlcpy(short_pass, pass, sizeof (short_pass)); + (void) __gen_dhkeys(public, secret, short_pass); - memcpy(crypt1, secret, HEXKEYBYTES); - memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); + (void) memcpy(crypt1, secret, HEXKEYBYTES); + (void) memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; - xencrypt(crypt1, pass); + xencrypt(crypt1, short_pass); if (status = setpublicmap(name, public, crypt1, pk_database, - nprinc, pass)) { + nprinc, short_pass)) { switch (pk_database) { case PK_YP: (void) fprintf(stderr, - "%s: unable to update NIS database (%u): %s\n", - program_name, status, - yperr_string(status)); + "%s: unable to update NIS database (%u): %s\n", + program_name, status, + yperr_string(status)); break; case PK_FILES: (void) fprintf(stderr, - "%s: hence, unable to update publickey database\n", - program_name); + "%s: hence, unable to update publickey database\n", + program_name); break; case PK_NISPLUS: (void) fprintf(stderr, - "%s: unable to update nisplus database\n", - program_name); + "%s: unable to update nisplus database\n", + program_name); break; default: (void) fprintf(stderr, - "%s: could not update unknown database: %d\n", - program_name, pk_database); + "%s: could not update unknown database: %d\n", + program_name, pk_database); } exit(1); } @@ -326,11 +326,11 @@ usage(void) { (void) fprintf(stderr, - "usage:\t%s -u username [-s ldap | nisplus | nis | files]\n", - program_name); + "usage:\t%s -u username [-s ldap | nisplus | nis | files]\n", + program_name); (void) fprintf(stderr, - "\t%s -h hostname [-s ldap | nisplus | nis | files]\n", - program_name); + "\t%s -h hostname [-s ldap | nisplus | nis | files]\n", + program_name); exit(1); } @@ -397,7 +397,7 @@ (void) sprintf(prompt, "Enter %s's login password:", pw->pw_name); - pass = getpass(prompt); + pass = getpassphrase(prompt); if (pass && strlen(pass) == 0) { (void) fprintf(stderr, "%s: Invalid password.\n", program_name); @@ -411,7 +411,7 @@ /* * Give another chance for typo */ - pass = getpass("Please retype password:"); + pass = getpassphrase("Please retype password:"); if (pass && strlen(pass) == 0) { (void) fprintf(stderr, "%s: Invalid password.\n", program_name); @@ -447,7 +447,7 @@ (void) sprintf(prompt, "Enter %s's root login password:", target_host); - pass = getpass(prompt); + pass = getpassphrase(prompt); if (!pass) { (void) fprintf(stderr, "%s: getpass failed.\n", @@ -469,7 +469,7 @@ (void) sprintf(prompt, "Please confirm %s's root login password:", target_host); - pass = getpass(prompt); + pass = getpassphrase(prompt); if (!pass) { (void) fprintf(stderr, "%s: getpass failed.\n",
--- a/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svc.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svc.c Wed Jul 01 22:27:19 2009 +0530 @@ -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,7 +19,7 @@ * 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. * * npd_svc.c @@ -28,8 +27,6 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <syslog.h> #include <string.h> #include <ctype.h> @@ -67,6 +64,31 @@ nispasswd_authresult *result; struct svc_req *rqstp; { + return (nispasswd_authenticate_common_svc(argp, + result, rqstp, NISPASSWD_VERS)); +} + +/* + * service routine for first part of the nispasswd update2 + * protocol. + */ +bool_t +nispasswd_authenticate_2_svc(argp, result, rqstp) +npd_request *argp; +nispasswd_authresult *result; +struct svc_req *rqstp; +{ + return (nispasswd_authenticate_common_svc(argp, + result, rqstp, NISPASSWD_VERS2)); +} + +bool_t +nispasswd_authenticate_common_svc(argp, result, rqstp, vers) +npd_request *argp; +nispasswd_authresult *result; +struct svc_req *rqstp; +rpcvers_t vers; +{ bool_t check_aging = TRUE; /* default == check */ bool_t same_user = TRUE; /* default == same user */ bool_t is_admin = FALSE; /* default == not an admin */ @@ -75,7 +97,6 @@ bool_t refresh = FALSE; /* default == do not refresh */ int ans = 0; char prin[NIS_MAXNAMELEN]; - unsigned char xpass[_NPD_PASSMAXLEN]; struct update_item *entry = NULL; nis_result *pass_res; nis_object *pobj; @@ -86,6 +107,22 @@ uint32_t rval, ident; keylen_t pkeylen; /* public key length (bits) */ algtype_t algtype; /* public key algorithm type */ + int passlen = __NPD2_MAXPASSBYTES; + unsigned char *xpass; + + if (vers == NISPASSWD_VERS) { + passlen = __NPD_MAXPASSBYTES; + } else if (vers == NISPASSWD_VERS2) { + passlen = __NPD2_MAXPASSBYTES; + } + + if ((xpass = malloc(passlen + 1)) == NULL) { + syslog(LOG_ERR, + "nispasswd_authenticate_common_svc: Out of memory"); + result->status = NPD_FAILED; + result->nispasswd_authresult_u.npd_err = NPD_SYSTEMERR; + return (TRUE); + } if (verbose) syslog(LOG_ERR, "received NIS+ auth request for %s", @@ -96,7 +133,7 @@ syslog(LOG_ERR, "not master for %s", argp->domain); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_NOTMASTER; - return (TRUE); + goto auth_free_xpass; } again: @@ -126,7 +163,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_BUFTOOSMALL; - return (TRUE); + goto auth_free_xpass; } (void) sprintf(prin, "%s.%s", argp->username, argp->domain); if (prin[strlen(prin) - 1] != '.') @@ -166,7 +203,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_PASSINVALID; - return (TRUE); + goto auth_free_xpass; } if (argp->ident == 0) { /* @@ -191,7 +228,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_IDENTINVALID; - return (TRUE); + goto auth_free_xpass; } } @@ -203,7 +240,7 @@ argp->username, argp->domain); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_NOSUCHENTRY; - return (TRUE); + goto auth_free_xpass; } switch (pass_res->status) { case NIS_SUCCESS: @@ -215,7 +252,7 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_NOSUCHENTRY; - return (TRUE); + goto auth_free_xpass; default: syslog(LOG_ERR, "NIS+ error (%d) getting passwd entry for %s", @@ -223,7 +260,7 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_NISERROR; - return (TRUE); + goto auth_free_xpass; } /* if user check if 'min' days have passed since 'lastchg' */ @@ -236,7 +273,7 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = ans; - return (TRUE); + goto auth_free_xpass; } /* if ans == NPD_NOSHDWINFO then aging cannot be enforced */ } @@ -261,7 +298,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_INVALIDARGS; - return (TRUE); + goto auth_free_xpass; } } @@ -277,27 +314,27 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_CKGENFAILED; - return (TRUE); + goto auth_free_xpass; } /* decrypt the passwd sent */ - if (argp->npd_authpass.npd_authpass_len != _NPD_PASSMAXLEN) { + if (argp->npd_authpass.npd_authpass_len != passlen) { syslog(LOG_ERR, "password length wrong"); (void) nis_freeresult(pass_res); result->status = NPD_TRYAGAIN; result->nispasswd_authresult_u.npd_err = NPD_PASSINVALID; - return (TRUE); + goto auth_free_xpass; } (void) memcpy(xpass, argp->npd_authpass.npd_authpass_val, - _NPD_PASSMAXLEN); + passlen); ivec.key.high = ivec.key.low = 0; if (AUTH_DES_KEY(pkeylen, algtype)) status = cbc_crypt(deskeys[0].c, (char *)xpass, - _NPD_PASSMAXLEN, DES_DECRYPT | DES_HW, + passlen, DES_DECRYPT | DES_HW, (char *)&ivec); else status = __cbc_triple_crypt(deskeys, (char *)xpass, - _NPD_PASSMAXLEN, DES_DECRYPT | DES_HW, + passlen, DES_DECRYPT | DES_HW, (char *)&ivec); if (DES_FAILED(status)) { @@ -305,7 +342,7 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_DECRYPTFAIL; - return (TRUE); + goto auth_free_xpass; } /* assign an ID and generate R on the first call of a session */ @@ -316,7 +353,7 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_SYSTEMERR; - return (TRUE); + goto auth_free_xpass; } (void) __npd_gen_rval(&randval); } else { @@ -331,7 +368,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_SYSTEMERR; - return (TRUE); + goto auth_free_xpass; } } else { if (strcmp(entry->ul_user, argp->username) != 0) { @@ -349,7 +386,7 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_ENCRYPTFAIL; - return (TRUE); + goto auth_free_xpass; } /* encrypt the passwd and compare with that stored in NIS+ */ if (same_user) { @@ -357,7 +394,7 @@ (void) nis_freeresult(pass_res); result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_NOPASSWD; - return (TRUE); + goto auth_free_xpass; } if (strcmp(crypt((const char *)xpass, (const char *)oldpass), oldpass) != 0) { @@ -397,7 +434,7 @@ } if (verbose) (void) __npd_print_entry(prin); - return (TRUE); + goto auth_free_xpass; } } else { if (is_admin == FALSE) { /* not privileged */ @@ -405,7 +442,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_PERMDENIED; - return (TRUE); + goto auth_free_xpass; } /* admin changing another users password */ if (__authenticate_admin(prin, (char *)xpass) == FALSE) { @@ -434,7 +471,7 @@ NPD_SYSTEMERR; } } - return (TRUE); + goto auth_free_xpass; } } /* done with pass_res */ @@ -448,7 +485,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_SYSTEMERR; - return (TRUE); + goto auth_free_xpass; } } else { if (entry->ul_oldpass != NULL) @@ -458,7 +495,7 @@ result->status = NPD_FAILED; result->nispasswd_authresult_u.npd_err = NPD_SYSTEMERR; - return (TRUE); + goto auth_free_xpass; } if (upd_entry == TRUE) { entry->ul_ident = ident; @@ -473,6 +510,10 @@ htonl(cryptbuf.key.low); if (verbose) (void) __npd_print_entry(prin); + +auth_free_xpass: + if (xpass != NULL) + free(xpass); return (TRUE); } @@ -487,9 +528,38 @@ nispasswd_updresult *res; struct svc_req *rqstp; { + return (nispasswd_update_common_svc((void *) updreq, + res, rqstp, NISPASSWD_VERS)); +} + +/* + * service routine for second part of the nispasswd update2 + * protocol. + */ +/* ARGSUSED2 */ +bool_t +nispasswd_update_2_svc(updreq, res, rqstp) +npd_update2 *updreq; +nispasswd_updresult *res; +struct svc_req *rqstp; +{ + return (nispasswd_update_common_svc((void *) updreq, + res, rqstp, NISPASSWD_VERS2)); +} + +/* + * service routine for second part of the nispasswd update common + * protocol. + */ +/* ARGSUSED2 */ +bool_t +nispasswd_update_common_svc(tmp_updreq, res, rqstp, vers) +void *tmp_updreq; +nispasswd_updresult *res; +struct svc_req *rqstp; +rpcvers_t vers; +{ struct update_item *entry; - npd_newpass cryptbuf; - passbuf pass; char *newpass, buf[NIS_MAXNAMELEN]; uint32_t rand; struct nis_result *pass_res = NULL, *mod_res = NULL; @@ -505,16 +575,56 @@ uint_t eobj_col_len; int pwflag = FALSE; int chg_passwd = TRUE; + char *pass; + int passlen = __NPD2_MAXPASSBYTES; + npd_newpass cryptbuf1; + npd_newpass2 cryptbuf2; + npd_update *updreq1; + npd_update2 *updreq2; + char *gecos; + char *shell; + + if (vers == NISPASSWD_VERS) { + passlen = __NPD_MAXPASSBYTES; + updreq1 = (npd_update *)tmp_updreq; + gecos = updreq1->pass_info.pw_gecos; + shell = updreq1->pass_info.pw_shell; + } else if (vers == NISPASSWD_VERS2) { + passlen = __NPD2_MAXPASSBYTES; + updreq2 = (npd_update2 *)tmp_updreq; + gecos = updreq2->pass_info.pw_gecos; + shell = updreq2->pass_info.pw_shell; + } + + if ((pass = malloc(passlen + 1)) == NULL) { + syslog(LOG_ERR, + "nispasswd_update_common_svc: Out of memory"); + res->status = NPD_FAILED; + res->nispasswd_updresult_u.npd_err = NPD_SYSTEMERR; + return (TRUE); + } /* set to success, and reset to error when warranted */ res->status = NPD_SUCCESS; - entry = (struct update_item *)__npd_item_by_key(updreq->ident); - if (entry == NULL) { - syslog(LOG_ERR, "invalid identifier: %ld", updreq->ident); - res->status = NPD_FAILED; - res->nispasswd_updresult_u.npd_err = NPD_IDENTINVALID; - return (TRUE); + if (vers == NISPASSWD_VERS) { + entry = (struct update_item *)__npd_item_by_key(updreq1->ident); + if (entry == NULL) { + syslog(LOG_ERR, "invalid identifier: %ld", + updreq1->ident); + res->status = NPD_FAILED; + res->nispasswd_updresult_u.npd_err = NPD_IDENTINVALID; + goto upd_free_pass; + } + } else if (vers == NISPASSWD_VERS2) { + entry = (struct update_item *)__npd_item_by_key(updreq2->ident); + if (entry == NULL) { + syslog(LOG_ERR, "invalid identifier: %ld", + updreq2->ident); + res->status = NPD_FAILED; + res->nispasswd_updresult_u.npd_err = NPD_IDENTINVALID; + goto upd_free_pass; + } } if (verbose) { @@ -528,19 +638,40 @@ */ for (; entry != NULL; entry = (struct update_item *)entry->ul_item.next) { - - /* decrypt R and new passwd */ - cryptbuf.npd_xrandval = ntohl(updreq->xnewpass.npd_xrandval); - for (i = 0; i < __NPD_MAXPASSBYTES; i++) - cryptbuf.pass[i] = updreq->xnewpass.pass[i]; + if (vers == NISPASSWD_VERS) { + /* decrypt R and new passwd */ + cryptbuf1.npd_xrandval = + ntohl(updreq1->xnewpass.npd_xrandval); + for (i = 0; i < passlen; i++) + cryptbuf1.pass[i] = updreq1->xnewpass.pass[i]; - if (! __npd_cbc_crypt(&rand, pass, __NPD_MAXPASSBYTES, - &cryptbuf, _NPD_PASSMAXLEN, DES_DECRYPT, - &entry->ul_key)) { - syslog(LOG_ERR, "failed to decrypt verifier"); - res->status = NPD_FAILED; - res->nispasswd_updresult_u.npd_err = NPD_DECRYPTFAIL; - return (TRUE); + if (! __npd_cbc_crypt(&rand, pass, passlen, + &cryptbuf1, _NPD_PASSMAXLEN, DES_DECRYPT, + &entry->ul_key)) { + syslog(LOG_ERR, "failed to decrypt verifier"); + res->status = NPD_FAILED; + res->nispasswd_updresult_u.npd_err = + NPD_DECRYPTFAIL; + goto upd_free_pass; + } + } else if (vers == NISPASSWD_VERS2) { + /* decrypt R and new passwd */ + + cryptbuf2.npd_xrandval = + ntohl(updreq2->xnewpass.npd_xrandval); + cryptbuf2.npd_pad = ntohl(updreq2->xnewpass.npd_pad); + for (i = 0; i < passlen; i++) + cryptbuf2.pass[i] = updreq2->xnewpass.pass[i]; + + if (! __npd2_cbc_crypt(&rand, pass, passlen, + &cryptbuf2, sizeof (cryptbuf2), DES_DECRYPT, + &entry->ul_key)) { + syslog(LOG_ERR, "failed to decrypt verifier"); + res->status = NPD_FAILED; + res->nispasswd_updresult_u.npd_err = + NPD_DECRYPTFAIL; + goto upd_free_pass; + } } /* check if R sent/decrypted matches cached R */ @@ -561,7 +692,7 @@ syslog(LOG_ERR, "update failed; no rand matches"); res->status = NPD_FAILED; res->nispasswd_updresult_u.npd_err = NPD_VERFINVALID; - return (TRUE); + goto upd_free_pass; } /* create passwd struct with this pass & gecos/shell */ @@ -572,7 +703,7 @@ entry->ul_user, entry->ul_domain); res->status = NPD_FAILED; res->nispasswd_updresult_u.npd_err = NPD_NOSUCHENTRY; - return (TRUE); + goto upd_free_pass; } switch (pass_res->status) { @@ -585,7 +716,7 @@ (void) nis_freeresult(pass_res); res->status = NPD_FAILED; res->nispasswd_updresult_u.npd_err = NPD_NOSUCHENTRY; - return (TRUE); + goto upd_free_pass; default: syslog(LOG_ERR, "NIS+ error (%d) getting passwd entry for %s", @@ -593,7 +724,7 @@ (void) nis_freeresult(pass_res); res->status = NPD_FAILED; res->nispasswd_updresult_u.npd_err = NPD_NISERROR; - return (TRUE); + goto upd_free_pass; } old_pass = ENTRY_VAL(pobj, 1); @@ -607,7 +738,7 @@ (void) memset(errlist, 0, sizeof (errlist)); /* if a gecos field is provided... */ - if (*updreq->pass_info.pw_gecos != '\0') { + if (*gecos != '\0') { chg_passwd = FALSE; if (__npd_can_do(NIS_MODIFY_ACC, pobj, entry->ul_item.name, 4) == FALSE) { @@ -619,17 +750,17 @@ errlist[0].npd_code = NPD_PERMDENIED; errlist[0].next = NULL; } else if (old_gecos == NULL || - strcmp(updreq->pass_info.pw_gecos, old_gecos) != 0) { + strcmp(gecos, old_gecos) != 0) { ecol[4].ec_value.ec_value_val = - updreq->pass_info.pw_gecos; + gecos; ecol[4].ec_value.ec_value_len = - strlen(updreq->pass_info.pw_gecos) + 1; + strlen(gecos) + 1; ecol[4].ec_flags = EN_MODIFIED; } } /* if a shell field is provided... */ - if (*updreq->pass_info.pw_shell != '\0') { + if (*shell != '\0') { chg_passwd = FALSE; if (__npd_can_do(NIS_MODIFY_ACC, pobj, entry->ul_item.name, 6) == FALSE) { @@ -654,11 +785,11 @@ errlist[0].next = NULL; } } else if (old_shell == NULL || - strcmp(updreq->pass_info.pw_shell, old_shell) != 0) { + strcmp(shell, old_shell) != 0) { ecol[6].ec_value.ec_value_val = - updreq->pass_info.pw_shell; + shell; ecol[6].ec_value.ec_value_len = - strlen(updreq->pass_info.pw_shell) + 1; + strlen(shell) + 1; ecol[6].ec_flags = EN_MODIFIED; } } @@ -866,6 +997,10 @@ if (mod_res) (void) nis_freeresult(mod_res); if (pass_res) (void) nis_freeresult(pass_res); if (entry) (void) free_upd_item(entry); + +upd_free_pass: + if (pass != NULL) + free(pass); return (TRUE); } @@ -1236,3 +1371,19 @@ return (1); } + +/* ARGSUSED */ +int +nispasswd_prog_2_freeresult(transp, xdr_result, result) +SVCXPRT *transp; +xdrproc_t xdr_result; +caddr_t result; +{ + + /* + * (void) xdr_free(xdr_result, result); + * Insert additional freeing code here, if needed + */ + + return (1); +}
--- a/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svcsubr.h Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svcsubr.h Wed Jul 01 22:27:19 2009 +0530 @@ -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,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * */ @@ -28,9 +27,8 @@ #ifndef _NPD_SVCSUBR_H #define _NPD_SVCSUBR_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <rpcsvc/yppasswd.h> +#include <rpcsvc/nispasswd.h> #ifdef __cplusplus extern "C" { @@ -53,8 +51,18 @@ bool_t nispasswd_authenticate_1_svc(npd_request *argp, nispasswd_authresult *result, struct svc_req *rqstp); +bool_t nispasswd_authenticate_2_svc(npd_request *argp, + nispasswd_authresult *result, struct svc_req *rqstp); +bool_t nispasswd_authenticate_common_svc(npd_request *argp, + nispasswd_authresult *result, struct svc_req *rqstp, rpcvers_t vers); + bool_t nispasswd_update_1_svc(npd_update *updreq, nispasswd_updresult *res, struct svc_req *rqstp); +bool_t nispasswd_update_2_svc(npd_update2 *updreq, nispasswd_updresult *res, + struct svc_req *rqstp); +bool_t nispasswd_update_common_svc(void *updreq, nispasswd_updresult *res, + struct svc_req *rqstp, rpcvers_t vers); + bool_t yppasswdproc_update_1_svc(struct yppasswd *yppass, int *result, struct svc_req *rqstp); @@ -70,6 +78,11 @@ extern bool_t __npd_cbc_crypt(uint32_t *val, char *str, unsigned int strsize, npd_newpass *buf, unsigned int bufsize, unsigned int mode, des_block *deskey); + +extern bool_t __npd2_cbc_crypt(uint32_t *val, char *str, unsigned int strsize, + npd_newpass2 *buf, unsigned int bufsize, unsigned int mode, + des_block *deskey); + extern void __free_nis_server(nis_server *server); #ifdef __cplusplus
--- a/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/rpc.nispasswdd.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/rpc.nispasswdd.c Wed Jul 01 22:27:19 2009 +0530 @@ -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 <stdlib.h> /* getenv, exit */ #include <signal.h> @@ -59,6 +56,8 @@ static void __msgout(const char *msg); static int __svc_priv_port_create(void); static void nispasswd_prog(struct svc_req *rqstp, register SVCXPRT *transp); +static void nispasswd_prog_ver2(struct svc_req *rqstp, + register SVCXPRT *transp); static void yppasswd_prog(struct svc_req *rqstp, register SVCXPRT *transp); static void set_rpc_gss_svc_names(void); @@ -83,7 +82,7 @@ if (max_attempts < 0) { fprintf(stderr, "%s: invalid number of maximum attempts\n", - argv[0]); + argv[0]); exit(1); } break; @@ -91,7 +90,7 @@ mins = atoi(optarg); if (mins <= 0) { fprintf(stderr, - "%s: invalid cache time\n", argv[0]); + "%s: invalid cache time\n", argv[0]); exit(1); } cache_time = (ulong_t)mins * 60; @@ -107,14 +106,14 @@ break; case 'Y': /* YP forward mode */ if (!(ypfwd = strdup(optarg))) { - fprintf(stderr, "%s: out of memory\n", argv[0]); - exit(1); + fprintf(stderr, "%s: out of memory\n", argv[0]); + exit(1); } break; case '?': fprintf(stderr, "Usage: %s [-a attempts] [-c minutes] [-D] [-g] [-v]\n", - argv[0]); + argv[0]); exit(1); } } @@ -129,7 +128,7 @@ if (geteuid() != (uid_t)0) { char err_string[256]; snprintf(err_string, sizeof (err_string), - "must be superuser to run %s", argv[0]); + "must be superuser to run %s", argv[0]); __msgout(err_string); exit(1); } @@ -160,11 +159,11 @@ if (debug == TRUE) (void) fprintf(stderr, "no host/address information for local host, %d\n", - status); + status); else syslog(LOG_ERR, "no host/address information for local host, %d", - status); + status); __msgout("exiting ..."); exit(1); } @@ -184,7 +183,7 @@ exit(1); } if ((strcmp(tagres[0].tag_val, "<Unknown Statistics>") == 0) || - (strcmp(tagres[1].tag_val, "<Unknown Statistics>") == 0)) { + (strcmp(tagres[1].tag_val, "<Unknown Statistics>") == 0)) { /* old server */ __msgout("NIS+ server does not support the new statistics tags"); @@ -227,12 +226,24 @@ exit(1); } if (svc_create(nispasswd_prog, NISPASSWD_PROG, NISPASSWD_VERS, - "circuit_v") == 0) { + "circuit_v") == 0) { __msgout("unable to create (NISPASSWD_PROG, NISPASSWD_VERS)"); __msgout(" ... exiting ..."); exit(1); } + if (rpcb_unset(NISPASSWD_PROG, NISPASSWD_VERS2, 0) == FALSE) { + __msgout("unable to de-register (NISPASSWD_PROG, NISPASSWD_VERS2)"); + __msgout(" ... exiting ..."); + exit(1); + } + if (svc_create(nispasswd_prog_ver2, NISPASSWD_PROG, NISPASSWD_VERS2, + "circuit_v") == 0) { + __msgout("unable to create (NISPASSWD_PROG, NISPASSWD_VERS2)"); + __msgout(" ... exiting ..."); + exit(1); + } + if (verbose == TRUE) __msgout("starting rpc.nispasswdd ..."); svc_run(); @@ -266,9 +277,9 @@ } while ((nconf = getnetconfig(handlep)) != 0 && - (nconf4 == 0 || nconf6 == 0)) { + (nconf4 == 0 || nconf6 == 0)) { if ((nconf->nc_semantics == NC_TPI_CLTS) && - strcmp(nconf->nc_proto, NC_UDP) == 0) { + strcmp(nconf->nc_proto, NC_UDP) == 0) { if (strcmp(nconf->nc_protofmly, NC_INET) == 0) nconf4 = nconf; else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) @@ -320,10 +331,10 @@ if (transp4 != 0) svc4 = svc_reg(transp4, YPPASSWDPROG, YPPASSWDVERS, - yppasswd_prog, nconf4); + yppasswd_prog, nconf4); if (transp6 != 0) svc6 = svc_reg(transp6, YPPASSWDPROG, YPPASSWDVERS, - yppasswd_prog, nconf6); + yppasswd_prog, nconf6); if (svc4 == 0 && svc6 == 0) { __msgout("unable to register (YPPASSWDPROG, YPPASSWDVERS)"); if (transp4 != 0) @@ -402,6 +413,71 @@ } static void +nispasswd_prog_ver2(rqstp, transp) +struct svc_req *rqstp; +register SVCXPRT *transp; +{ + + union { + npd_request nispasswd_authenticate_2_arg; + npd_update2 nispasswd_update_2_arg; + } argument; + union { + nispasswd_authresult nispasswd_authenticate_2_res; + nispasswd_updresult nispasswd_update_2_res; + } result; + bool_t retval; + xdrproc_t xdr_argument, xdr_result; + bool_t (*local)(char *, void *, struct svc_req *); + + switch (rqstp->rq_proc) { + case NULLPROC: + __msgout("received NIS+ null proc call"); + (void) svc_sendreply(transp, + (xdrproc_t)xdr_void, (char *)NULL); + return; + + case NISPASSWD_AUTHENTICATE: + xdr_argument = (xdrproc_t)xdr_npd_request; + xdr_result = (xdrproc_t)xdr_nispasswd_authresult; + local = (bool_t (*) (char *, void *, struct svc_req *)) + nispasswd_authenticate_2_svc; + break; + + case NISPASSWD_UPDATE: + xdr_argument = (xdrproc_t)xdr_npd_update2; + xdr_result = (xdrproc_t)xdr_nispasswd_updresult; + local = (bool_t (*) (char *, void *, struct svc_req *)) + nispasswd_update_2_svc; + break; + + default: + svcerr_noproc(transp); + return; + } + (void) memset((char *)&argument, 0, sizeof (argument)); + if (svc_getargs(transp, xdr_argument, (caddr_t)&argument) == 0) { + svcerr_decode(transp); + return; + } + (void) memset((char *)&result, 0, sizeof (result)); + retval = (bool_t)(*local)((char *)&argument, (void *)&result, rqstp); + if (retval == TRUE && (svc_sendreply(transp, xdr_result, + (char *)&result) == 0)) { + svcerr_systemerr(transp); + } + if (svc_freeargs(transp, xdr_argument, (caddr_t)&argument) == 0) { + __msgout("unable to free arguments"); + exit(1); + } + if (nispasswd_prog_2_freeresult(transp, xdr_result, + (caddr_t)&result) == 0) + __msgout("unable to free results"); + + /* NOTREACHED */ +} + +static void yppasswd_prog(rqstp, transp) struct svc_req *rqstp; register SVCXPRT *transp; @@ -504,7 +580,7 @@ /* '@' + NUL = 2 */ if (strlen(lh) + strlen(NIS_SVCNAME_NISPASSWD) + 2 > - sizeof (svc_name)) { + sizeof (svc_name)) { syslog(LOG_ERR, "can't set RPC GSS service name: svc_name bufsize too small"); __nis_release_mechanisms(mechs); @@ -519,6 +595,7 @@ for (mpp = mechs; *mpp; mpp++) { mechanism_t *mp = *mpp; + bool_t val; if (AUTH_DES_COMPAT_CHK(mp)) break; @@ -526,21 +603,44 @@ if (! VALID_MECH_ENTRY(mp)) continue; - if (rpc_gss_set_svc_name(svc_name, mp->mechname, - 0, NISPASSWD_PROG, - NISPASSWD_VERS)) { + val = rpc_gss_set_svc_name(svc_name, mp->mechname, + 0, NISPASSWD_PROG, + NISPASSWD_VERS); + if (val) { if (verbose) syslog(LOG_INFO, "RPC GSS service name for mechanism '%s' set", - mp->mechname); + mp->mechname); } else { rpc_gss_error_t err; rpc_gss_get_error(&err); syslog(LOG_ERR, -"can't set RPC GSS svc name '%s' for mech '%s': RPC GSS err = %d, sys err = %d", - svc_name, mp->mechname, - err.rpc_gss_error, err.system_error); + "can't set RPC GSS svc name '%s'" + "for mech '%s': RPC GSS err = %d," + "sys err = %d", + svc_name, mp->mechname, + err.rpc_gss_error, err.system_error); + } + + val = rpc_gss_set_svc_name(svc_name, mp->mechname, + 0, NISPASSWD_PROG, + NISPASSWD_VERS2); + if (val) { + if (verbose) + syslog(LOG_INFO, + "RPC GSS service name for mechanism '%s' set", + mp->mechname); + } else { + rpc_gss_error_t err; + + rpc_gss_get_error(&err); + syslog(LOG_ERR, + "can't set RPC GSS svc name '%s'" + "for mech '%s': RPC GSS err = %d," + "sys err = %d", + svc_name, mp->mechname, + err.rpc_gss_error, err.system_error); } } __nis_release_mechanisms(mechs);
--- a/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedescred.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedescred.c Wed Jul 01 22:27:19 2009 +0530 @@ -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. @@ -22,12 +21,10 @@ /* * makedescred.c * - * Copyright (c) 1988-1992,2001 by 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" - /* * makedescred.c * @@ -45,6 +42,7 @@ #include <nsswitch.h> #include <netdb.h> #include <rpcsvc/nis.h> +#include <rpcsvc/nispasswd.h> #include <rpcsvc/nis_dhext.h> #include <rpc/key_prot.h> #include "nisaddcred.h" @@ -84,7 +82,7 @@ struct key_netstarg netst; netst.st_pub_key[0] = 0; - memcpy(netst.st_priv_key, secret, HEXKEYBYTES); + (void) memcpy(netst.st_priv_key, secret, HEXKEYBYTES); netst.st_netname = netname; #ifdef NFS_AUTH @@ -134,6 +132,7 @@ { nis_object *obj = init_entry(); char *pass; + char short_pass[DESCREDPASSLEN + 1]; uid_t uid; char public[HEXKEYBYTES + 1]; char secret[HEXKEYBYTES + 1]; @@ -166,17 +165,18 @@ if (pass == 0) return (0); + (void) strlcpy(short_pass, pass, sizeof (short_pass)); /* Get password with which to encrypt secret key. */ (void) printf("%s key pair for %s (%s).\n", - addition? "Adding" : "Updating", netname, nis_princ); + addition? "Adding" : "Updating", netname, nis_princ); /* Encrypt secret key */ - (void) __gen_dhkeys(public, secret, pass); - memcpy(crypt1, secret, HEXKEYBYTES); - memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); + (void) __gen_dhkeys(public, secret, short_pass); + (void) memcpy(crypt1, secret, HEXKEYBYTES); + (void) memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; - xencrypt(crypt1, pass); + xencrypt(crypt1, short_pass); /* Now we have a key pair, build up the cred entry */ @@ -205,8 +205,8 @@ obj->zo_domain = domain; /* owner: r, group: rmcd */ obj->zo_access = ((NIS_READ_ACC<<16)| - (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC| - NIS_DESTROY_ACC)<<8); + (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC| + NIS_DESTROY_ACC)<<8); status = add_cred_obj(obj, domain); } else { obj->EN_data.en_cols.en_cols_val[3].ec_flags |= EN_MODIFIED; @@ -236,8 +236,8 @@ if (mechlist = (mechanism_t **)__nis_get_mechanisms(FALSE)) { while (mechlist[i]) { status = make_dhext_cred(nis_princ, netname, - domain, - mechlist[i]->alias); + domain, + mechlist[i]->alias); if (!status) return (status); i++;
--- a/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedhextcred.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedhextcred.c Wed Jul 01 22:27:19 2009 +0530 @@ -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. @@ -22,12 +21,10 @@ /* * makedescred.c * - * Copyright (c) 1997 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" - /* * makedescred.c * @@ -45,11 +42,13 @@ #include <nsswitch.h> #include <netdb.h> #include <rpcsvc/nis.h> +#include <rpcsvc/nispasswd.h> #include <rpcsvc/nis_dhext.h> #include <rpc/key_prot.h> #include "nisaddcred.h" extern char *getpass(); +extern char *getpassphrase(); extern char *crypt(); extern int add_cred_obj(nis_object *, char *); extern nis_error auth_exists(char *, char *, char *, char *); @@ -82,11 +81,11 @@ static char policy[256]; int previous = 0; - memset((char *)policy, 0, 256); + (void) memset((char *)policy, 0, 256); for (look = conf->lookups; look; look = look->next) { if (previous) - strcat(policy, " "); + (void) strcat(policy, " "); strcat(policy, look->service_name); previous = 1; } @@ -106,8 +105,8 @@ is_switch_policy(struct __nsw_switchconfig *conf, char *target) { return (conf && conf->lookups && - strcmp(conf->lookups->service_name, target) == 0 && - conf->lookups->next == NULL); + strcmp(conf->lookups->service_name, target) == 0 && + conf->lookups->next == NULL); } @@ -124,25 +123,25 @@ if (no_switch_policy(conf)) { if (!is_switch_policy(default_conf, target_service)) { fprintf(stderr, - "\n%s\n There is no publickey entry in %s.\n", - head_msg, __NSW_CONFIG_FILE); + "\n%s\n There is no publickey entry in %s.\n", + head_msg, __NSW_CONFIG_FILE); fprintf(stderr, " The default publickey policy is \"publickey: %s\".\n", - switch_policy_str(default_conf)); + switch_policy_str(default_conf)); policy_correct = 0; } } else if (!is_switch_policy(conf, target_service)) { fprintf(stderr, "\n%s\n The publickey entry in %s is \"publickey: %s\".\n", - head_msg, __NSW_CONFIG_FILE, - switch_policy_str(conf)); + head_msg, __NSW_CONFIG_FILE, + switch_policy_str(conf)); policy_correct = 0; } /* should we exit ? */ if (policy_correct == 0) fprintf(stderr, " It should be \"publickey: %s\"%s.\n\n", - target_service, tail_msg); + target_service, tail_msg); if (conf) __nsw_freeconfig(conf); @@ -160,17 +159,17 @@ /* Sanity check 0. Do we have a nis+ principal name to work with? */ if (nis_princ == NULL) { fprintf(stderr, - "%s: you must create a \"local\" credential first.\n", - program_name); + "%s: you must create a \"local\" credential first.\n", + program_name); fprintf(stderr, - "rerun this command as : %s local \n", program_name); + "rerun this command as : %s local \n", program_name); return (0); } /* Sanity check 1. We only deal with one type of netnames. */ if (strncmp(netname, OPSYS, OPSYS_LEN) != 0) { fprintf(stderr, "%s: unrecognized netname type: '%s'.\n", - program_name, netname); + program_name, netname); return (0); } @@ -179,7 +178,7 @@ if (strcasecmp(princdomain, domain) != 0) { fprintf(stderr, "%s: domain of principal '%s' does not match destination domain '%s'.\n", - program_name, nis_princ, domain); + program_name, nis_princ, domain); fprintf(stderr, "Should only add DES credential of principal in its home domain\n"); return (0); @@ -192,7 +191,7 @@ netdomain = (char *)strchr(netname, '@'); if (! netdomain) { fprintf(stderr, "%s: invalid netname, missing @: '%s'. \n", - program_name, netname); + program_name, netname); return (0); } if (netname[strlen(netname)-1] == '.') @@ -210,7 +209,7 @@ /* Check publickey policy and warn user if it is not NIS+ */ check_switch_policy("publickey", "nisplus", &publickey_default, - "WARNING:", " when using NIS+"); + "WARNING:", " when using NIS+"); /* Another principal owns same credentials? (exits if that happens) */ (void) auth_exists(nis_princ, netname, authtype, domain); @@ -231,13 +230,13 @@ if (keylen == mechs[mcount]->keylen && algtype == mechs[mcount]->algtype) { if (key_setnet_g(netname, secret, - mechs[mcount]->keylen, - NULL, 0, - mechs[mcount]->algtype) + mechs[mcount]->keylen, + NULL, 0, + mechs[mcount]->algtype) < 0) { fprintf(stderr, "Could not set %s's %s secret key\n", - netname, flavor); + netname, flavor); fprintf(stderr, "May be the keyserv is down?\n"); return (0); @@ -325,14 +324,14 @@ if ((rootfd = open(ROOTKEY_FILE, O_WRONLY+O_CREAT, 0600)) < 0) { perror("Could not open /etc/.rootkey for writing"); fprintf(stderr, - "Attempting to restore original /etc/.rootkey\n"); + "Attempting to restore original /etc/.rootkey\n"); rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); goto rootkey_err; } if (!(rootfile = fdopen(rootfd, "w"))) { perror("Could not open /etc/.rootkey for writing"); fprintf(stderr, - "Attempting to restore original /etc/.rootkey\n"); + "Attempting to restore original /etc/.rootkey\n"); close(rootfd); unlink(ROOTKEY_FILE); rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); @@ -341,7 +340,7 @@ if (!(bakfile = fopen(ROOTKEY_FILE_BACKUP, "r"))) { perror("Could not open /etc/.rootkey.bak for reading"); fprintf(stderr, - "Attempting to restore original /etc/.rootkey\n"); + "Attempting to restore original /etc/.rootkey\n"); fclose(rootfile); unlink(ROOTKEY_FILE); rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE); @@ -400,7 +399,7 @@ rootkey_err: fprintf(stderr, "WARNING: Could not write %s key to /etc/.rootkey\n", - flavor); + flavor); } @@ -431,14 +430,14 @@ if (! pw) { fprintf(stderr, "%s: unable to locate password record for uid %d\n", - program_name, uid); + program_name, uid); return (0); } spw = getspnam(pw->pw_name); if (!spw) { fprintf(stderr, "%s: unable to locate password record for uid 0\n", - program_name); + program_name); return (0); } login_password = spw->sp_pwdp; @@ -460,14 +459,14 @@ sprintf(prompt, "Enter login password:"); else if (uid == 0) { sprintf(prompt, "Enter %s's root login password:", - target_host); + target_host); } else sprintf(prompt, "Enter %s's login password:", - pw->pw_name); - pass = getpass(prompt); + pw->pw_name); + pass = getpassphrase(prompt); if (strlen(pass) == 0) { (void) fprintf(stderr, "%s: Password unchanged.\n", - program_name); + program_name); return (0); } strcpy(password, pass); @@ -481,7 +480,7 @@ else { fprintf(stderr, "%s: %s: password differs from login password.\n", - program_name, force? "WARNING" : "ERROR"); + program_name, force? "WARNING" : "ERROR"); if (!force) return (0); } @@ -489,10 +488,10 @@ /* Check for mis-typed password */ if (!passwords_matched) { - pass = getpass("Retype password:"); + pass = getpassphrase("Retype password:"); if (strcmp(password, pass) != 0) { (void) fprintf(stderr, "%s: password incorrect.\n", - program_name); + program_name); return (0); } } @@ -532,6 +531,7 @@ uid_t uid; static char *pass; char *public, *secret, *crypt1; + char short_pass[DESCREDPASSLEN + 1]; char authtype[MECH_MAXATNAME]; char target_host[MAXHOSTNAMELEN+1]; int same_host = 0; @@ -573,6 +573,8 @@ if (!pass) goto badstatus; + (void) strlcpy(short_pass, pass, sizeof (short_pass)); + /* Get password with which to encrypt secret key. */ (void) printf("%s %s key pair for %s (%s).\n", addition? "Adding" : "Updating", flavor, @@ -585,9 +587,9 @@ goto badstatus; /* Encrypt secret key */ - if (!(__gen_dhkeys_g(public, secret, kl, at, pass))) + if (!(__gen_dhkeys_g(public, secret, kl, at, short_pass))) goto badstatus; - if (!(xencrypt_g(secret, kl, at, pass, netname, &crypt1, TRUE))) + if (!(xencrypt_g(secret, kl, at, short_pass, netname, &crypt1, TRUE))) goto badstatus; /* Now we have a key pair, build up the cred entry */
--- a/usr/src/head/rpcsvc/nispasswd.x Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/head/rpcsvc/nispasswd.x Wed Jul 01 22:27:19 2009 +0530 @@ -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. @@ -22,12 +21,13 @@ /* * NIS+ password update protocol * - * Copyright (c) 1994, 1997 by Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * ident "%Z%%M% %I% %E% SMI" */ +%#include <limits.h> + /* * Protocol description: * Request from client: @@ -151,6 +151,21 @@ passwd_info pass_info; /* other information */ }; +%#define DESCREDPASSLEN sizeof (des_block) +const __NPD2_MAXPASSBYTES = 256; /* _PASS_MAX */ + +struct npd_newpass2 { + unsigned int npd_xrandval; /* R */ + opaque pass[__NPD2_MAXPASSBYTES]; /* "clear" new passwd */ + unsigned int npd_pad; /* pad size to modulo des_block */ +}; + +struct npd_update2 { + unsigned int ident; /* identifier */ + npd_newpass2 xnewpass; /* encrypted */ + passwd_info pass_info; /* other information */ +}; + struct nispasswd_verf { unsigned int npd_xid; /* encrypted identifier */ unsigned int npd_xrandval; /* encrypted R */ @@ -191,4 +206,16 @@ */ nispasswd_updresult NISPASSWD_UPDATE(npd_update) = 2; } = 1; + + version NISPASSWD_VERS2 { + /* + * authenticate passwd update request + */ + nispasswd_authresult NISPASSWD_AUTHENTICATE(npd_request) = 1; + + /* + * send new passwd information + */ + nispasswd_updresult NISPASSWD_UPDATE(npd_update2) = 2; + } = 2; } = 100303;
--- a/usr/src/lib/libnsl/common/llib-lnsl Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/lib/libnsl/common/llib-lnsl Wed Jul 01 22:27:19 2009 +0530 @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -446,6 +446,9 @@ bool_t __npd_cbc_crypt(uint32_t *val, char *str, uint_t strsize, npd_newpass *buf, uint_t bufsize, uint_t mode, des_block *deskey); +bool_t __npd2_cbc_crypt(uint32_t *val, char *str, uint_t strsize, + npd_newpass2 *buf, uint_t bufsize, uint_t mode, + des_block *deskey); /* print_obj.c */ void nis_print_rights(u_int r);
--- a/usr/src/lib/libnsl/common/mapfile-vers Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/lib/libnsl/common/mapfile-vers Wed Jul 01 22:27:19 2009 +0530 @@ -587,6 +587,7 @@ __nis_ss_used; __nis_translate_mechanism; nis_write_obj; + __npd2_cbc_crypt; __npd_cbc_crypt; __npd_ecb_crypt; __nsl_dom;
--- a/usr/src/lib/libnsl/nis/gen/npd_lib.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/lib/libnsl/nis/gen/npd_lib.c Wed Jul 01 22:27:19 2009 +0530 @@ -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. @@ -21,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,8 +29,6 @@ * and the client-side for NIS+ passwd update deamon. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "mt.h" #include <string.h> #include <memory.h> @@ -72,12 +69,12 @@ IXDR_PUT_U_INT32(ixdr, *val2); status = ecb_crypt((char *)deskey, (char *)buf, - bufsize, mode | DES_HW); + bufsize, mode | DES_HW); if (DES_FAILED(status)) return (FALSE); } else { status = ecb_crypt((char *)deskey, (char *)buf, - bufsize, mode | DES_HW); + bufsize, mode | DES_HW); if (DES_FAILED(status)) return (FALSE); @@ -106,8 +103,6 @@ int32_t *ixdr; des_block ivec; - if (bufsize > MAX_KEY_CRYPT_LEN) - return (FALSE); ivec.key.low = ivec.key.high = 0; ixdr = (int32_t *)buf; if (mode == DES_ENCRYPT) { @@ -119,12 +114,12 @@ buf->pass[i] = '\0'; status = cbc_crypt((char *)deskey, (char *)buf, - bufsize, mode | DES_HW, (char *)&ivec); + bufsize, mode | DES_HW, (char *)&ivec); if (DES_FAILED(status)) return (FALSE); } else { status = cbc_crypt((char *)deskey, (char *)buf, - bufsize, mode | DES_HW, (char *)&ivec); + bufsize, mode | DES_HW, (char *)&ivec); if (DES_FAILED(status)) return (FALSE); @@ -136,3 +131,50 @@ } return (TRUE); } + +/* + * encrypt/decrypt R (val) and password (str) + * return FALSE on failure and TRUE on success + */ +bool_t +__npd2_cbc_crypt( + uint32_t *val, + char *str, + unsigned int strsize, + npd_newpass2 *buf, + unsigned int bufsize, + unsigned int mode, + des_block *deskey) +{ + int status, i; + int32_t *ixdr; + des_block ivec; + + ivec.key.low = ivec.key.high = 0; + ixdr = (int32_t *)buf; + if (mode == DES_ENCRYPT) { + if ((strsize + 8) > bufsize) + return (FALSE); + IXDR_PUT_U_INT32(ixdr, *val); + (void) strcpy((char *)buf->pass, str); + for (i = strsize; i < __NPD2_MAXPASSBYTES; i++) + buf->pass[i] = '\0'; + buf->npd_pad = 0; + status = cbc_crypt((char *)deskey, (char *)buf, + bufsize, mode | DES_HW, (char *)&ivec); + if (DES_FAILED(status)) + return (FALSE); + } else { + status = cbc_crypt((char *)deskey, (char *)buf, + bufsize, mode | DES_HW, (char *)&ivec); + + if (DES_FAILED(status)) + return (FALSE); + + *val = IXDR_GET_U_INT32(ixdr); + if (strlen((char *)buf->pass) > strsize) + return (FALSE); + (void) strcpy(str, (char *)buf->pass); + } + return (TRUE); +}
--- a/usr/src/lib/passwdutil/nisplus_attr.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/lib/passwdutil/nisplus_attr.c Wed Jul 01 22:27:19 2009 +0530 @@ -462,7 +462,7 @@ struct spwd *spw; char *pword; int len; - char newpw[_PASS_MAX_XPG+1]; + char newpw[_PASS_MAX+1]; statebuf = (struct statebuf *)buf; pw = statebuf->pwd; @@ -508,8 +508,10 @@ * 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; @@ -736,7 +738,7 @@ char *domain; nis_result *cred_res; nis_result *handle; - char *newpw; + char short_newpw[DESCREDPASSLEN+1], *short_newpwp = NULL; entry_col ecol[5]; nis_object *eobj; @@ -786,7 +788,8 @@ return (PWU_SUCCESS); } - newpw = buf->spwd->sp_pwdp; + (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; @@ -805,10 +808,11 @@ reencrypt_tries++; newcryptsecret = reencrypt_secret(oldcryptsecret, oldrpcpw, - newpw, uid, keylen, algtype); + short_newpwp, uid, keylen, algtype); - if (newcryptsecret == NULL) + if (newcryptsecret == NULL) { continue; + } reencrypt_success++; @@ -829,7 +833,7 @@ "[cname=%s.%s,auth_type=%s],cred.%s", name, domain, authtype, NIS_RES_OBJECT(handle)->zo_domain) > sizeof (mname)-1) { - (void) memset(newpw, '\0', strlen(newpw)); + (void) memset(short_newpw, '\0', strlen(short_newpw)); (void) memset(oldrpcpw, '\0', strlen(oldrpcpw)); free(newcryptsecret); return (PWU_RECOVERY_ERR); @@ -854,7 +858,8 @@ (void) nis_freeresult(mres); } - (void) memset(newpw, '\0', strlen(newpw)); + (void) memset(short_newpw, '\0', strlen(short_newpw)); + short_newpwp = NULL; (void) memset(oldrpcpw, '\0', strlen(oldrpcpw)); if (reencrypt_tries > 0 && mod_entry == 0) { @@ -903,6 +908,7 @@ int retval; int npd_res; nispasswd_error *errlist = NULL; + char short_opass[DESCREDPASSLEN+1], *short_opassp = NULL; statebuf = (struct statebuf *)buf; @@ -924,9 +930,12 @@ 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, oldpw) == 0) { + 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; @@ -1015,7 +1024,7 @@ * We therefore try to update the credentials directly. */ retval = nisplus_update_cred(name, - oldrpcpw ? oldrpcpw : oldpw, rep, buf); + oldrpcpw ? oldrpcpw : short_opassp, rep, buf); } else { /* We don't update creds for gecos/shell updates */ retval = PWU_SUCCESS; @@ -1035,7 +1044,6 @@ auth_destroy(clnt->cl_auth); clnt_destroy(clnt); } - return (retval); } @@ -1060,7 +1068,10 @@ 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; @@ -1177,15 +1188,16 @@ 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(result); - + 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 : oldpw, - rep, buf); + retval = nisplus_update_cred(name, oldrpcpw ? oldrpcpw + : short_opassp, rep, buf); return (retval); @@ -1205,26 +1217,30 @@ struct statebuf *statebuf; int result = PWU_SUCCESS; uid_t cur_euid; - char short_pw[_PASS_MAX_XPG+1], short_rpcpw[_PASS_MAX_XPG+1]; - char *short_pwptr = NULL, *short_rpcpwptr = NULL; + 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(short_pw, oldpw, sizeof (short_pw)); - short_pwptr = short_pw; - } + (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, short_pwptr, + result = nisplus_old_proto(name, pw_ptr, short_rpcpwptr, rep, buf); } @@ -1233,9 +1249,8 @@ if (getuid() != 0) (void) seteuid(getuid()); - result = nisplus_new_proto(name, short_pwptr, + result = nisplus_new_proto(name, pw_ptr, short_rpcpwptr, rep, buf); - (void) seteuid(cur_euid); }
--- a/usr/src/lib/passwdutil/npd_clnt.c Wed Jul 01 08:42:32 2009 -0700 +++ b/usr/src/lib/passwdutil/npd_clnt.c Wed Jul 01 22:27:19 2009 +0530 @@ -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,7 +19,7 @@ * 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. */ @@ -31,8 +30,6 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdlib.h> #include <syslog.h> #include <string.h> @@ -48,6 +45,7 @@ #include <memory.h> #include <sys/time.h> #include <unistd.h> +#include <sys/types.h> #define _NPD_PASSMAXLEN 16 @@ -57,6 +55,10 @@ 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 @@ -96,7 +98,7 @@ continue; if (hexkey = __nis_dhext_extract_pkey(pkey, - mp->keylen, mp->algtype)) { + mp->keylen, mp->algtype)) { if ((*keybuf = malloc(strlen(hexkey) + 1)) == 0) { syslog(LOG_ERR, "malloc failed"); @@ -118,7 +120,7 @@ /* 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)) { + AUTH_DES_KEYLEN, AUTH_DES_ALGTYPE)) { if ((*keybuf = malloc(strlen(hexkey) + 1)) == NULL) { syslog(LOG_ERR, "malloc failed"); return (FALSE); @@ -159,6 +161,7 @@ nis_server *master_srv; char buf[NIS_MAXNAMELEN]; CLIENT *tmpclnt = NULL; + rpcvers_t vers; if (domain == NULL || *domain == '\0') domain = nis_local_directory(); @@ -224,10 +227,16 @@ * 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 */ - tmpclnt = nis_make_rpchandle_gss_svc_ruid(master_srv, 0, NISPASSWD_PROG, - NISPASSWD_VERS, ZMH_VC+ZMH_AUTH, 0, 0, NULL, - NIS_SVCNAME_NISPASSWD); + 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); @@ -270,7 +279,8 @@ npd_request req_arg; nispasswd_authresult res; des_block ivec; - unsigned char xpass[_NPD_PASSMAXLEN]; + unsigned char xpass[_NPD_PASSMAXLEN+1]; + unsigned char xpass2[__NPD2_MAXPASSBYTES+1]; des_block cryptbuf; int cryptstat; int i; @@ -287,28 +297,54 @@ (void) memset((char *)&req_arg, 0, sizeof (req_arg)); (void) memset((char *)&res, 0, sizeof (res)); - /* encrypt the passwd with the common des key */ - if (strlen(oldpass) > (size_t)_NPD_PASSMAXLEN) { - *err = NPD_BUFTOOSMALL; - return (NPD_FAILED); - } - (void) strcpy((char *)xpass, oldpass); - for (i = strlen(oldpass); i < _NPD_PASSMAXLEN; i++) - xpass[i] = '\0'; + 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, + 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); + 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; @@ -317,8 +353,13 @@ 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; - req_arg.npd_authpass.npd_authpass_len = _NPD_PASSMAXLEN; - req_arg.npd_authpass.npd_authpass_val = xpass; + 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, @@ -383,10 +424,15 @@ nispasswd_error **errlst; /* error list on partial success, returned */ { npd_update send_arg; + npd_update2 send_arg2; nispasswd_updresult result; - npd_newpass cryptbuf; + 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) || @@ -394,37 +440,76 @@ *err = NPD_INVALIDARGS; return (NPD_FAILED); } - (void) memset((char *)&send_arg, 0, sizeof (send_arg)); - (void) memset((char *)&result, 0, sizeof (result)); + + 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)); - send_arg.ident = ident; + 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; - if (! __npd_cbc_crypt(&randval, newpass, strlen(newpass), - &cryptbuf, _NPD_PASSMAXLEN, DES_ENCRYPT, deskey)) { + /* gecos */ + send_arg.pass_info.pw_gecos = gecos; + + /* shell */ + send_arg.pass_info.pw_shell = shell; - *err = NPD_ENCRYPTFAIL; - return (NPD_FAILED); - } - tmp_xrval = cryptbuf.npd_xrandval; - cryptbuf.npd_xrandval = htonl(tmp_xrval); - send_arg.xnewpass = cryptbuf; + 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); + } - /* gecos */ - send_arg.pass_info.pw_gecos = gecos; + } 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)); - /* shell */ - send_arg.pass_info.pw_shell = shell; + 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); - 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) { + send_arg2.xnewpass = cryptbuf2; + /* gecos */ + send_arg2.pass_info.pw_gecos = gecos; + /* shell */ + send_arg2.pass_info.pw_shell = shell; - /* printed to stderr */ - (void) clnt_perror(clnt, - "update call to rpc.nispasswdd failed"); - *err = NPD_SRVNOTRESP; - return (NPD_FAILED); + 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: