17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*36e852a1SRaja Andra * Common Development and Distribution License (the "License"). 6*36e852a1SRaja Andra * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*36e852a1SRaja Andra * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <stdio.h> 277c478bd9Sstevel@tonic-gate #include <errno.h> 287c478bd9Sstevel@tonic-gate #include <stdlib.h> 297c478bd9Sstevel@tonic-gate #include <string.h> 307c478bd9Sstevel@tonic-gate #include <sys/errno.h> 317c478bd9Sstevel@tonic-gate #include <pwd.h> 327c478bd9Sstevel@tonic-gate #include <unistd.h> 337c478bd9Sstevel@tonic-gate #include <syslog.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <netdb.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 387c478bd9Sstevel@tonic-gate #include <rpcsvc/yppasswd.h> 397c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 407c478bd9Sstevel@tonic-gate #include <rpcsvc/yp_prot.h> 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #include "passwdutil.h" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate int nis_getattr(char *name, attrlist *item, pwu_repository_t *rep); 457c478bd9Sstevel@tonic-gate int nis_getpwnam(char *name, attrlist *items, pwu_repository_t *rep, 467c478bd9Sstevel@tonic-gate void **buf); 477c478bd9Sstevel@tonic-gate int nis_update(attrlist *items, pwu_repository_t *rep, void *buf); 48*36e852a1SRaja Andra int nis_putpwnam(char *name, char *oldpw, pwu_repository_t *rep, void *buf); 497c478bd9Sstevel@tonic-gate int nis_user_to_authenticate(char *user, pwu_repository_t *rep, 507c478bd9Sstevel@tonic-gate char **auth_user, int *privileged); 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* 537c478bd9Sstevel@tonic-gate * nis function pointer table, used by passwdutil_init to initialize 547c478bd9Sstevel@tonic-gate * the global Repository-OPerations table "rops" 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate struct repops nis_repops = { 577c478bd9Sstevel@tonic-gate NULL, /* checkhistory */ 587c478bd9Sstevel@tonic-gate nis_getattr, 597c478bd9Sstevel@tonic-gate nis_getpwnam, 607c478bd9Sstevel@tonic-gate nis_update, 617c478bd9Sstevel@tonic-gate nis_putpwnam, 627c478bd9Sstevel@tonic-gate nis_user_to_authenticate, 637c478bd9Sstevel@tonic-gate NULL, /* lock */ 647c478bd9Sstevel@tonic-gate NULL /* unlock */ 657c478bd9Sstevel@tonic-gate }; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* 687c478bd9Sstevel@tonic-gate * structure used to keep state between get/update/put calls 697c478bd9Sstevel@tonic-gate */ 707c478bd9Sstevel@tonic-gate typedef struct { 717c478bd9Sstevel@tonic-gate char *domain; 727c478bd9Sstevel@tonic-gate char *master; 737c478bd9Sstevel@tonic-gate char *scratch; 747c478bd9Sstevel@tonic-gate int scratchlen; 757c478bd9Sstevel@tonic-gate char *c2scratch; 767c478bd9Sstevel@tonic-gate int c2scratchlen; 777c478bd9Sstevel@tonic-gate struct passwd *pwd; 787c478bd9Sstevel@tonic-gate } nisbuf_t; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* 817c478bd9Sstevel@tonic-gate * Are we a 'privileged' process? Yes if we are running on the 827c478bd9Sstevel@tonic-gate * NIS server AND we are root... 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate int 857c478bd9Sstevel@tonic-gate nis_privileged(nisbuf_t *nisbuf) 867c478bd9Sstevel@tonic-gate { 877c478bd9Sstevel@tonic-gate char thishost[MAXHOSTNAMELEN]; 887c478bd9Sstevel@tonic-gate if (gethostname(thishost, sizeof (thishost)) == -1) { 897c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "passwdutil.so: Can't get hostname"); 907c478bd9Sstevel@tonic-gate return (0); 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate if (strcmp(nisbuf->master, thishost) != 0) 947c478bd9Sstevel@tonic-gate return (0); 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* We're running on the NIS server. */ 977c478bd9Sstevel@tonic-gate return (getuid() == 0); 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate /* 1017c478bd9Sstevel@tonic-gate * nis_to_pwd() 1027c478bd9Sstevel@tonic-gate * 1037c478bd9Sstevel@tonic-gate * convert password-entry-line to "struct passwd" 1047c478bd9Sstevel@tonic-gate */ 1057c478bd9Sstevel@tonic-gate void 1067c478bd9Sstevel@tonic-gate nis_to_pwd(char *nis, struct passwd *pwd) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate pwd->pw_name = strsep(&nis, ":"); 1097c478bd9Sstevel@tonic-gate pwd->pw_passwd = strsep(&nis, ":"); 1107c478bd9Sstevel@tonic-gate pwd->pw_uid = atoi(strsep(&nis, ":")); 1117c478bd9Sstevel@tonic-gate pwd->pw_gid = atoi(strsep(&nis, ":")); 1127c478bd9Sstevel@tonic-gate pwd->pw_gecos = strsep(&nis, ":"); 1137c478bd9Sstevel@tonic-gate pwd->pw_dir = strsep(&nis, ":"); 1147c478bd9Sstevel@tonic-gate pwd->pw_shell = nis; 1157c478bd9Sstevel@tonic-gate if (pwd->pw_shell[0]) 1167c478bd9Sstevel@tonic-gate pwd->pw_shell[strlen(pwd->pw_shell)-1] = '\0'; 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate /* 1207c478bd9Sstevel@tonic-gate * nis_user_to_authenticate(name, rep, auth_user, privileged) 1217c478bd9Sstevel@tonic-gate * 1227c478bd9Sstevel@tonic-gate */ 1237c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1247c478bd9Sstevel@tonic-gate int 1257c478bd9Sstevel@tonic-gate nis_user_to_authenticate(char *user, pwu_repository_t *rep, 1267c478bd9Sstevel@tonic-gate char **auth_user, int *privileged) 1277c478bd9Sstevel@tonic-gate { 1287c478bd9Sstevel@tonic-gate nisbuf_t *buf = NULL; 1297c478bd9Sstevel@tonic-gate int res; 1307c478bd9Sstevel@tonic-gate attrlist attr_tmp[1]; 1317c478bd9Sstevel@tonic-gate uid_t uid; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate /* 1347c478bd9Sstevel@tonic-gate * special NIS case: don't bother to get "root" from NIS 1357c478bd9Sstevel@tonic-gate */ 1367c478bd9Sstevel@tonic-gate if (strcmp(user, "root") == 0) 1377c478bd9Sstevel@tonic-gate return (PWU_NOT_FOUND); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate attr_tmp[0].type = ATTR_UID; 1407c478bd9Sstevel@tonic-gate attr_tmp[0].next = NULL; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate res = nis_getpwnam(user, &attr_tmp[0], rep, (void **)&buf); 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate if (res != PWU_SUCCESS) 1457c478bd9Sstevel@tonic-gate return (res); 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if (nis_privileged(buf)) { 1487c478bd9Sstevel@tonic-gate *privileged = 1; 1497c478bd9Sstevel@tonic-gate *auth_user = NULL; 1507c478bd9Sstevel@tonic-gate res = PWU_SUCCESS; 1517c478bd9Sstevel@tonic-gate } else { 1527c478bd9Sstevel@tonic-gate uid = getuid(); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate *privileged = (uid == (uid_t)0); 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate /* root, or user herself can change attributes */ 1577c478bd9Sstevel@tonic-gate if (uid == 0 || uid == buf->pwd->pw_uid) { 1587c478bd9Sstevel@tonic-gate *auth_user = strdup(user); 1597c478bd9Sstevel@tonic-gate res = PWU_SUCCESS; 1607c478bd9Sstevel@tonic-gate } else { 1617c478bd9Sstevel@tonic-gate res = PWU_DENIED; 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate /* 1667c478bd9Sstevel@tonic-gate * Do not release buf->domain. 1677c478bd9Sstevel@tonic-gate * It's been set by yp_get_default_domain() 1687c478bd9Sstevel@tonic-gate * and must not be freed. 1697c478bd9Sstevel@tonic-gate * See man page yp_get_default_domain(3NSL) 1707c478bd9Sstevel@tonic-gate * for details. 1717c478bd9Sstevel@tonic-gate */ 1727c478bd9Sstevel@tonic-gate if (buf->master) 1737c478bd9Sstevel@tonic-gate free(buf->master); 1747c478bd9Sstevel@tonic-gate if (buf->scratch) 1757c478bd9Sstevel@tonic-gate free(buf->scratch); 1767c478bd9Sstevel@tonic-gate if (buf->c2scratch) 1777c478bd9Sstevel@tonic-gate free(buf->c2scratch); 1787c478bd9Sstevel@tonic-gate free(buf->pwd); 1797c478bd9Sstevel@tonic-gate free(buf); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate return (res); 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate /* 1867c478bd9Sstevel@tonic-gate * nis_getattr(name, items, rep) 1877c478bd9Sstevel@tonic-gate * 1887c478bd9Sstevel@tonic-gate * get account attributes specified in 'items' 1897c478bd9Sstevel@tonic-gate */ 1907c478bd9Sstevel@tonic-gate int 1917c478bd9Sstevel@tonic-gate nis_getattr(char *name, attrlist *items, pwu_repository_t *rep) 1927c478bd9Sstevel@tonic-gate { 1937c478bd9Sstevel@tonic-gate nisbuf_t *nisbuf = NULL; 1947c478bd9Sstevel@tonic-gate struct passwd *pw; 1957c478bd9Sstevel@tonic-gate attrlist *w; 1967c478bd9Sstevel@tonic-gate int res; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate res = nis_getpwnam(name, items, rep, (void **)&nisbuf); 1997c478bd9Sstevel@tonic-gate if (res != PWU_SUCCESS) 2007c478bd9Sstevel@tonic-gate return (res); 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate pw = nisbuf->pwd; 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate for (w = items; w != NULL; w = w->next) { 2057c478bd9Sstevel@tonic-gate switch (w->type) { 2067c478bd9Sstevel@tonic-gate case ATTR_NAME: 2077c478bd9Sstevel@tonic-gate if ((w->data.val_s = strdup(pw->pw_name)) == NULL) 2087c478bd9Sstevel@tonic-gate res = PWU_NOMEM; 2097c478bd9Sstevel@tonic-gate break; 2107c478bd9Sstevel@tonic-gate case ATTR_COMMENT: 2117c478bd9Sstevel@tonic-gate if ((w->data.val_s = strdup(pw->pw_comment)) == NULL) 2127c478bd9Sstevel@tonic-gate res = PWU_NOMEM; 2137c478bd9Sstevel@tonic-gate break; 2147c478bd9Sstevel@tonic-gate case ATTR_GECOS: 2157c478bd9Sstevel@tonic-gate if ((w->data.val_s = strdup(pw->pw_gecos)) == NULL) 2167c478bd9Sstevel@tonic-gate res = PWU_NOMEM; 2177c478bd9Sstevel@tonic-gate break; 2187c478bd9Sstevel@tonic-gate case ATTR_HOMEDIR: 2197c478bd9Sstevel@tonic-gate if ((w->data.val_s = strdup(pw->pw_dir)) == NULL) 2207c478bd9Sstevel@tonic-gate res = PWU_NOMEM; 2217c478bd9Sstevel@tonic-gate break; 2227c478bd9Sstevel@tonic-gate case ATTR_SHELL: 2237c478bd9Sstevel@tonic-gate if ((w->data.val_s = strdup(pw->pw_shell)) == NULL) 2247c478bd9Sstevel@tonic-gate res = PWU_NOMEM; 2257c478bd9Sstevel@tonic-gate break; 2267c478bd9Sstevel@tonic-gate case ATTR_PASSWD: 2277c478bd9Sstevel@tonic-gate case ATTR_PASSWD_SERVER_POLICY: 2287c478bd9Sstevel@tonic-gate if ((w->data.val_s = strdup(pw->pw_passwd)) == NULL) 2297c478bd9Sstevel@tonic-gate res = PWU_NOMEM; 2307c478bd9Sstevel@tonic-gate break; 2317c478bd9Sstevel@tonic-gate case ATTR_REP_NAME: 2327c478bd9Sstevel@tonic-gate if ((w->data.val_s = strdup("nis")) == NULL) 2337c478bd9Sstevel@tonic-gate res = PWU_NOMEM; 2347c478bd9Sstevel@tonic-gate break; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /* integer values */ 2377c478bd9Sstevel@tonic-gate case ATTR_UID: 2387c478bd9Sstevel@tonic-gate w->data.val_i = nisbuf->pwd->pw_uid; 2397c478bd9Sstevel@tonic-gate break; 2407c478bd9Sstevel@tonic-gate case ATTR_GID: 2417c478bd9Sstevel@tonic-gate w->data.val_i = nisbuf->pwd->pw_gid; 2427c478bd9Sstevel@tonic-gate break; 2437c478bd9Sstevel@tonic-gate case ATTR_LSTCHG: 2447c478bd9Sstevel@tonic-gate case ATTR_MIN: 2457c478bd9Sstevel@tonic-gate case ATTR_MAX: 2467c478bd9Sstevel@tonic-gate case ATTR_WARN: 2477c478bd9Sstevel@tonic-gate case ATTR_INACT: 2487c478bd9Sstevel@tonic-gate case ATTR_EXPIRE: 2497c478bd9Sstevel@tonic-gate case ATTR_FLAG: 2507c478bd9Sstevel@tonic-gate case ATTR_AGE: 2517c478bd9Sstevel@tonic-gate w->data.val_i = -1; /* not used for NIS */ 2527c478bd9Sstevel@tonic-gate break; 2537c478bd9Sstevel@tonic-gate default: 2547c478bd9Sstevel@tonic-gate break; 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate /* 2597c478bd9Sstevel@tonic-gate * Do not release nisbuf->domain. 2607c478bd9Sstevel@tonic-gate * It's been set by yp_get_default_domain() 2617c478bd9Sstevel@tonic-gate * and must not be freed. 2627c478bd9Sstevel@tonic-gate * See man page yp_get_default_domain(3NSL) 2637c478bd9Sstevel@tonic-gate * for details. 2647c478bd9Sstevel@tonic-gate */ 2657c478bd9Sstevel@tonic-gate if (nisbuf->master) 2667c478bd9Sstevel@tonic-gate free(nisbuf->master); 2677c478bd9Sstevel@tonic-gate if (nisbuf->scratch) 2687c478bd9Sstevel@tonic-gate free(nisbuf->scratch); 2697c478bd9Sstevel@tonic-gate if (nisbuf->c2scratch) 2707c478bd9Sstevel@tonic-gate free(nisbuf->c2scratch); 2717c478bd9Sstevel@tonic-gate free(nisbuf->pwd); 2727c478bd9Sstevel@tonic-gate free(nisbuf); 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate return (res); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate /* 2787c478bd9Sstevel@tonic-gate * nis_getpwnam(name, items, rep) 2797c478bd9Sstevel@tonic-gate * 2807c478bd9Sstevel@tonic-gate * Get the account information of user 'name' 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2837c478bd9Sstevel@tonic-gate int 2847c478bd9Sstevel@tonic-gate nis_getpwnam(char *name, attrlist *items, pwu_repository_t *rep, 2857c478bd9Sstevel@tonic-gate void **buf) 2867c478bd9Sstevel@tonic-gate { 2877c478bd9Sstevel@tonic-gate nisbuf_t *nisbuf; 2887c478bd9Sstevel@tonic-gate int nisresult; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate nisbuf = calloc(sizeof (*nisbuf), 1); 2917c478bd9Sstevel@tonic-gate if (nisbuf == NULL) 2927c478bd9Sstevel@tonic-gate return (PWU_NOMEM); 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate nisbuf->pwd = malloc(sizeof (struct passwd)); 2957c478bd9Sstevel@tonic-gate if (nisbuf->pwd == NULL) { 2967c478bd9Sstevel@tonic-gate free(nisbuf); 2977c478bd9Sstevel@tonic-gate return (PWU_NOMEM); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate /* 3017c478bd9Sstevel@tonic-gate * Do not release nisbuf->domain. 3027c478bd9Sstevel@tonic-gate * It is going to be set by yp_get_default_domain() 3037c478bd9Sstevel@tonic-gate * and must not be freed. 3047c478bd9Sstevel@tonic-gate * See man page yp_get_default_domain(3NSL) 3057c478bd9Sstevel@tonic-gate * for details. 3067c478bd9Sstevel@tonic-gate */ 3077c478bd9Sstevel@tonic-gate if (yp_get_default_domain(&nisbuf->domain) != 0) { 3087c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "passwdutil.so: can't get domain"); 3097c478bd9Sstevel@tonic-gate free(nisbuf->pwd); 3107c478bd9Sstevel@tonic-gate free(nisbuf); 3117c478bd9Sstevel@tonic-gate return (PWU_SERVER_ERROR); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate if (yp_master(nisbuf->domain, "passwd.byname", &nisbuf->master) != 0) { 3157c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 3167c478bd9Sstevel@tonic-gate "passwdutil.so: can't get master for passwd map"); 3177c478bd9Sstevel@tonic-gate if (nisbuf->master) 3187c478bd9Sstevel@tonic-gate free(nisbuf->master); 3197c478bd9Sstevel@tonic-gate free(nisbuf->pwd); 3207c478bd9Sstevel@tonic-gate free(nisbuf); 3217c478bd9Sstevel@tonic-gate return (PWU_SERVER_ERROR); 3227c478bd9Sstevel@tonic-gate } 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate nisresult = yp_match(nisbuf->domain, "passwd.byname", name, 3257c478bd9Sstevel@tonic-gate strlen(name), &(nisbuf->scratch), 3267c478bd9Sstevel@tonic-gate &(nisbuf->scratchlen)); 3277c478bd9Sstevel@tonic-gate if (nisresult != 0) { 3287c478bd9Sstevel@tonic-gate (void) free(nisbuf->pwd); 3297c478bd9Sstevel@tonic-gate if (nisbuf->scratch) 3307c478bd9Sstevel@tonic-gate (void) free(nisbuf->scratch); 3317c478bd9Sstevel@tonic-gate if (nisbuf->master) 3327c478bd9Sstevel@tonic-gate (void) free(nisbuf->master); 3337c478bd9Sstevel@tonic-gate (void) free(nisbuf); 3347c478bd9Sstevel@tonic-gate return (PWU_NOT_FOUND); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate nis_to_pwd(nisbuf->scratch, nisbuf->pwd); 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate /* 3407c478bd9Sstevel@tonic-gate * check for the C2 security flag "##" in the passwd field. 3417c478bd9Sstevel@tonic-gate * If the first 2 chars in the passwd field is "##", get 3427c478bd9Sstevel@tonic-gate * the user's passwd from passwd.adjunct.byname map. 3437c478bd9Sstevel@tonic-gate * The lookup to this passwd.adjunct.byname map will only 3447c478bd9Sstevel@tonic-gate * succeed if the caller's uid is 0 because only root user 3457c478bd9Sstevel@tonic-gate * can use privilege port. 3467c478bd9Sstevel@tonic-gate */ 3477c478bd9Sstevel@tonic-gate if (nisbuf->pwd->pw_passwd[0] == '#' && 3487c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_passwd[1] == '#') { 3497c478bd9Sstevel@tonic-gate char *key = &nisbuf->pwd->pw_passwd[2]; 3507c478bd9Sstevel@tonic-gate int keylen; 3517c478bd9Sstevel@tonic-gate char *p; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate keylen = strlen(key); 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate nisresult = yp_match(nisbuf->domain, "passwd.adjunct.byname", 3567c478bd9Sstevel@tonic-gate key, keylen, &(nisbuf->c2scratch), 3577c478bd9Sstevel@tonic-gate &(nisbuf->c2scratchlen)); 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate if (nisresult == 0 && nisbuf->c2scratch != NULL) { 3607c478bd9Sstevel@tonic-gate /* Skip username (first field), and pick up password */ 3617c478bd9Sstevel@tonic-gate p = nisbuf->c2scratch; 3627c478bd9Sstevel@tonic-gate (void) strsep(&p, ":"); 3637c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_passwd = strsep(&p, ":"); 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate *buf = (void *)nisbuf; 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate return (PWU_SUCCESS); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate /* 3737c478bd9Sstevel@tonic-gate * nis_update(items, rep, buf) 3747c478bd9Sstevel@tonic-gate * 3757c478bd9Sstevel@tonic-gate * update the information in "buf" with the attribute/values 3767c478bd9Sstevel@tonic-gate * specified in "items". 3777c478bd9Sstevel@tonic-gate */ 3787c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3797c478bd9Sstevel@tonic-gate int 3807c478bd9Sstevel@tonic-gate nis_update(attrlist *items, pwu_repository_t *rep, void *buf) 3817c478bd9Sstevel@tonic-gate { 3827c478bd9Sstevel@tonic-gate attrlist *p; 3837c478bd9Sstevel@tonic-gate nisbuf_t *nisbuf = (nisbuf_t *)buf; 3847c478bd9Sstevel@tonic-gate char *salt; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate for (p = items; p != NULL; p = p->next) { 3877c478bd9Sstevel@tonic-gate switch (p->type) { 3887c478bd9Sstevel@tonic-gate case ATTR_NAME: 3897c478bd9Sstevel@tonic-gate break; 3907c478bd9Sstevel@tonic-gate /* 3917c478bd9Sstevel@tonic-gate * Nothing special needs to be done for 3927c478bd9Sstevel@tonic-gate * server policy 3937c478bd9Sstevel@tonic-gate */ 3947c478bd9Sstevel@tonic-gate case ATTR_PASSWD: 3957c478bd9Sstevel@tonic-gate case ATTR_PASSWD_SERVER_POLICY: 3967c478bd9Sstevel@tonic-gate salt = crypt_gensalt( 3977c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_passwd, nisbuf->pwd); 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate if (salt == NULL) { 4007c478bd9Sstevel@tonic-gate if (errno == ENOMEM) 4017c478bd9Sstevel@tonic-gate return (PWU_NOMEM); 4027c478bd9Sstevel@tonic-gate else { 4037c478bd9Sstevel@tonic-gate /* algorithm problem? */ 4047c478bd9Sstevel@tonic-gate syslog(LOG_AUTH | LOG_ALERT, 4057c478bd9Sstevel@tonic-gate "passwdutil: crypt_gensalt " 4067c478bd9Sstevel@tonic-gate "%m"); 4077c478bd9Sstevel@tonic-gate return (PWU_UPDATE_FAILED); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_passwd = crypt(p->data.val_s, salt); 4117c478bd9Sstevel@tonic-gate free(salt); 4127c478bd9Sstevel@tonic-gate break; 4137c478bd9Sstevel@tonic-gate case ATTR_UID: 4147c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_uid = (uid_t)p->data.val_i; 4157c478bd9Sstevel@tonic-gate break; 4167c478bd9Sstevel@tonic-gate case ATTR_GID: 4177c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_gid = (gid_t)p->data.val_i; 4187c478bd9Sstevel@tonic-gate break; 4197c478bd9Sstevel@tonic-gate case ATTR_AGE: 4207c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_age = p->data.val_s; 4217c478bd9Sstevel@tonic-gate break; 4227c478bd9Sstevel@tonic-gate case ATTR_COMMENT: 4237c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_comment = p->data.val_s; 4247c478bd9Sstevel@tonic-gate break; 4257c478bd9Sstevel@tonic-gate case ATTR_GECOS: 4267c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_gecos = p->data.val_s; 4277c478bd9Sstevel@tonic-gate break; 4287c478bd9Sstevel@tonic-gate case ATTR_HOMEDIR: 4297c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_dir = p->data.val_s; 4307c478bd9Sstevel@tonic-gate break; 4317c478bd9Sstevel@tonic-gate case ATTR_SHELL: 4327c478bd9Sstevel@tonic-gate nisbuf->pwd->pw_shell = p->data.val_s; 4337c478bd9Sstevel@tonic-gate break; 4347c478bd9Sstevel@tonic-gate case ATTR_LSTCHG: 4357c478bd9Sstevel@tonic-gate case ATTR_MIN: 4367c478bd9Sstevel@tonic-gate case ATTR_MAX: 4377c478bd9Sstevel@tonic-gate case ATTR_WARN: 4387c478bd9Sstevel@tonic-gate case ATTR_INACT: 4397c478bd9Sstevel@tonic-gate case ATTR_EXPIRE: 4407c478bd9Sstevel@tonic-gate case ATTR_FLAG: 4417c478bd9Sstevel@tonic-gate default: 4427c478bd9Sstevel@tonic-gate break; 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate return (PWU_SUCCESS); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate /* 449*36e852a1SRaja Andra * nis_putpwnam(name, oldpw, rep, buf) 4507c478bd9Sstevel@tonic-gate * 4517c478bd9Sstevel@tonic-gate * Update the NIS server. The passwd structure in buf will be sent to 4527c478bd9Sstevel@tonic-gate * the server for user "name" authenticating with password "oldpw". 4537c478bd9Sstevel@tonic-gate */ 4547c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 4557c478bd9Sstevel@tonic-gate int 456*36e852a1SRaja Andra nis_putpwnam(char *name, char *oldpw, pwu_repository_t *rep, 4577c478bd9Sstevel@tonic-gate void *buf) 4587c478bd9Sstevel@tonic-gate { 4597c478bd9Sstevel@tonic-gate nisbuf_t *nisbuf = (nisbuf_t *)buf; 4607c478bd9Sstevel@tonic-gate struct yppasswd yppasswd; 4617c478bd9Sstevel@tonic-gate struct netconfig *nconf; 4627c478bd9Sstevel@tonic-gate int ok; 4637c478bd9Sstevel@tonic-gate enum clnt_stat ans; 4647c478bd9Sstevel@tonic-gate CLIENT *client; 4657c478bd9Sstevel@tonic-gate struct timeval timeout; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate if (strcmp(name, "root") == 0) 4687c478bd9Sstevel@tonic-gate return (PWU_NOT_FOUND); 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate yppasswd.oldpass = oldpw ? oldpw : ""; 4717c478bd9Sstevel@tonic-gate yppasswd.newpw = *nisbuf->pwd; 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate /* 4747c478bd9Sstevel@tonic-gate * If we are privileged, we create a ticlts connection to the 4757c478bd9Sstevel@tonic-gate * NIS server so that it can check our credentials 4767c478bd9Sstevel@tonic-gate */ 4777c478bd9Sstevel@tonic-gate if (nis_privileged(nisbuf)) { 4787c478bd9Sstevel@tonic-gate nconf = getnetconfigent("ticlts"); 4797c478bd9Sstevel@tonic-gate if (!nconf) { 4807c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 4817c478bd9Sstevel@tonic-gate "passwdutil.so: Couldn't get netconfig entry"); 4827c478bd9Sstevel@tonic-gate return (PWU_SYSTEM_ERROR); 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate client = clnt_tp_create(nisbuf->master, YPPASSWDPROG, 4857c478bd9Sstevel@tonic-gate YPPASSWDVERS, nconf); 4867c478bd9Sstevel@tonic-gate freenetconfigent(nconf); 4877c478bd9Sstevel@tonic-gate } else { 4887c478bd9Sstevel@tonic-gate /* Try IPv6 first */ 4897c478bd9Sstevel@tonic-gate client = clnt_create(nisbuf->master, YPPASSWDPROG, 4907c478bd9Sstevel@tonic-gate YPPASSWDVERS, "udp6"); 4917c478bd9Sstevel@tonic-gate if (client == NULL) 4927c478bd9Sstevel@tonic-gate client = clnt_create(nisbuf->master, YPPASSWDPROG, 4937c478bd9Sstevel@tonic-gate YPPASSWDVERS, "udp"); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate if (client == NULL) { 4977c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 4987c478bd9Sstevel@tonic-gate "passwdutil.so: couldn't create client to YP master"); 4997c478bd9Sstevel@tonic-gate return (PWU_SERVER_ERROR); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate timeout.tv_usec = 0; 5037c478bd9Sstevel@tonic-gate timeout.tv_sec = 55; /* ndp uses 55 seconds */ 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate ans = CLNT_CALL(client, YPPASSWDPROC_UPDATE, xdr_yppasswd, 5067c478bd9Sstevel@tonic-gate (char *)&yppasswd, xdr_int, (char *)&ok, timeout); 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate if (nisbuf->pwd) 5097c478bd9Sstevel@tonic-gate (void) free(nisbuf->pwd); 5107c478bd9Sstevel@tonic-gate if (nisbuf->master) 5117c478bd9Sstevel@tonic-gate (void) free(nisbuf->master); 5127c478bd9Sstevel@tonic-gate if (nisbuf->scratch) 5137c478bd9Sstevel@tonic-gate (void) free(nisbuf->scratch); 5147c478bd9Sstevel@tonic-gate if (nisbuf->c2scratch) 5157c478bd9Sstevel@tonic-gate (void) free(nisbuf->c2scratch); 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate (void) clnt_destroy(client); 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate if (ans != RPC_SUCCESS) { 5207c478bd9Sstevel@tonic-gate return (PWU_UPDATE_FAILED); 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate /* These errors are obtained from the yppasswdd.c code */ 5247c478bd9Sstevel@tonic-gate switch (ok) { 5257c478bd9Sstevel@tonic-gate case 2: return (PWU_DENIED); 5267c478bd9Sstevel@tonic-gate case 8: return (PWU_BUSY); 5277c478bd9Sstevel@tonic-gate case 9: return (PWU_SERVER_ERROR); 5287c478bd9Sstevel@tonic-gate case 4: return (PWU_NOT_FOUND); 5297c478bd9Sstevel@tonic-gate case 3: return (PWU_NO_CHANGE); 5307c478bd9Sstevel@tonic-gate case 7: return (PWU_DENIED); 5317c478bd9Sstevel@tonic-gate case 0: return (PWU_SUCCESS); 5327c478bd9Sstevel@tonic-gate default: return (PWU_SYSTEM_ERROR); 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate } 535