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 5cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6cb5caa98Sdjl * 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. 23cb5caa98Sdjl * Use is subject to license terms. 24cb5caa98Sdjl */ 25cb5caa98Sdjl /* 267c478bd9Sstevel@tonic-gate * getspent.c 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate * lib/nsswitch/compat/getspent.c -- name-service-switch backend for getspnam() 297c478bd9Sstevel@tonic-gate * It looks in /etc/shadow; if it finds shadow entries there that begin 307c478bd9Sstevel@tonic-gate * with "+" or "-", it consults other services. By default it uses NIS (YP), 317c478bd9Sstevel@tonic-gate * but the user can override this with a "passwd_compat" entry in 327c478bd9Sstevel@tonic-gate * /etc/nsswitch.conf, e.g. 33*36e852a1SRaja Andra * passwd_compat: ldap 347c478bd9Sstevel@tonic-gate * The main criterion for this code is that it behave in the same way as 357c478bd9Sstevel@tonic-gate * the code for getpwnam() and friends (in getpwent.c). Note that it uses 367c478bd9Sstevel@tonic-gate * the same nsswitch.conf entry, not a separate entry for "shadow_compat". 377c478bd9Sstevel@tonic-gate * 387c478bd9Sstevel@tonic-gate * Caveats: 397c478bd9Sstevel@tonic-gate * - More than one source may be specified, with the usual switch semantics, 407c478bd9Sstevel@tonic-gate * but having multiple sources here is definitely odd. 417c478bd9Sstevel@tonic-gate * - People who recursively specify "compat" deserve what they get. 427c478bd9Sstevel@tonic-gate * - Entries that begin with "+@" or "-@" are interpreted using 437c478bd9Sstevel@tonic-gate * getnetgrent() and innetgr(), which use the "netgroup" entry in 447c478bd9Sstevel@tonic-gate * /etc/nsswitch.conf. If the sources for "passwd_compat" and "netgroup" 457c478bd9Sstevel@tonic-gate * differ, everything should work fine, but the semantics will be pretty 467c478bd9Sstevel@tonic-gate * confusing. 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #include <shadow.h> 507c478bd9Sstevel@tonic-gate #include <string.h> 517c478bd9Sstevel@tonic-gate #include <stdlib.h> 527c478bd9Sstevel@tonic-gate #include "compat_common.h" 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(db_root); 557c478bd9Sstevel@tonic-gate 56cb5caa98Sdjl static void 577c478bd9Sstevel@tonic-gate _nss_initf_shadow_compat(p) 587c478bd9Sstevel@tonic-gate nss_db_params_t *p; 597c478bd9Sstevel@tonic-gate { 607c478bd9Sstevel@tonic-gate p->name = NSS_DBNAM_SHADOW; 617c478bd9Sstevel@tonic-gate p->config_name = NSS_DBNAM_PASSWD_COMPAT; 627c478bd9Sstevel@tonic-gate p->default_config = NSS_DEFCONF_PASSWD_COMPAT; 637c478bd9Sstevel@tonic-gate } 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate static const char * 667c478bd9Sstevel@tonic-gate get_spnamp(argp) 677c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp; 687c478bd9Sstevel@tonic-gate { 697c478bd9Sstevel@tonic-gate struct spwd *s = (struct spwd *)argp->returnval; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate return (s->sp_namp); 727c478bd9Sstevel@tonic-gate } 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate static int 757c478bd9Sstevel@tonic-gate check_spnamp(argp) 767c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp; 777c478bd9Sstevel@tonic-gate { 787c478bd9Sstevel@tonic-gate struct spwd *s = (struct spwd *)argp->returnval; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate return (strcmp(s->sp_namp, argp->key.name) == 0); 817c478bd9Sstevel@tonic-gate } 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static nss_status_t 847c478bd9Sstevel@tonic-gate getbyname(be, a) 857c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 867c478bd9Sstevel@tonic-gate void *a; 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate return (_nss_compat_XY_all(be, argp, check_spnamp, 917c478bd9Sstevel@tonic-gate NSS_DBOP_SHADOW_BYNAME)); 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 957c478bd9Sstevel@tonic-gate static int 967c478bd9Sstevel@tonic-gate merge_spents(be, argp, fields) 977c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 987c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp; 997c478bd9Sstevel@tonic-gate const char **fields; 1007c478bd9Sstevel@tonic-gate { 1017c478bd9Sstevel@tonic-gate struct spwd *sp = (struct spwd *)argp->buf.result; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* 1047c478bd9Sstevel@tonic-gate * Don't allow overriding of the username; apart from that, 1057c478bd9Sstevel@tonic-gate * anything is fair game. 1067c478bd9Sstevel@tonic-gate */ 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate if (fields[1] != 0) { 1097c478bd9Sstevel@tonic-gate size_t namelen = strlen(sp->sp_namp) + 1; 1107c478bd9Sstevel@tonic-gate size_t passlen = strlen(fields[1]) + 1; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate /* ===> Probably merits an explanation... */ 1137c478bd9Sstevel@tonic-gate if (namelen + passlen > argp->buf.buflen) { 1147c478bd9Sstevel@tonic-gate return (NSS_STR_PARSE_ERANGE); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate if (sp->sp_namp != argp->buf.buffer) { 117cb5caa98Sdjl (void) memmove(argp->buf.buffer, 118cb5caa98Sdjl sp->sp_namp, namelen); 1197c478bd9Sstevel@tonic-gate sp->sp_namp = argp->buf.buffer; 1207c478bd9Sstevel@tonic-gate } 121cb5caa98Sdjl (void) memcpy(argp->buf.buffer + namelen, 122cb5caa98Sdjl fields[1], passlen); 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate #define override(field, longp) \ 1267c478bd9Sstevel@tonic-gate if ((field) != 0) { \ 1277c478bd9Sstevel@tonic-gate char *end; \ 1287c478bd9Sstevel@tonic-gate long val = strtol(field, &end, 10); \ 1297c478bd9Sstevel@tonic-gate \ 1307c478bd9Sstevel@tonic-gate if (*end == '\0') { \ 1317c478bd9Sstevel@tonic-gate *(longp) = val; \ 1327c478bd9Sstevel@tonic-gate } else { \ 1337c478bd9Sstevel@tonic-gate return (NSS_STR_PARSE_PARSE); \ 1347c478bd9Sstevel@tonic-gate } \ 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /* do not override last changed date, it never gets reset. */ 1387c478bd9Sstevel@tonic-gate /* override(fields[2], &sp->sp_lstchg); */ 1397c478bd9Sstevel@tonic-gate override(fields[3], &sp->sp_min); 1407c478bd9Sstevel@tonic-gate override(fields[4], &sp->sp_max); 1417c478bd9Sstevel@tonic-gate override(fields[5], &sp->sp_warn); 1427c478bd9Sstevel@tonic-gate override(fields[6], &sp->sp_inact); 1437c478bd9Sstevel@tonic-gate override(fields[7], &sp->sp_expire); 1447c478bd9Sstevel@tonic-gate override(fields[8], &sp->sp_flag); 145cb5caa98Sdjl 146cb5caa98Sdjl /* 147cb5caa98Sdjl * if asked, return the data in /etc file format 148cb5caa98Sdjl */ 149cb5caa98Sdjl if (be->return_string_data == 1) { 150cb5caa98Sdjl int n; 15121b41e80Ssdussud char b[16 * 7]; 152cb5caa98Sdjl 153cb5caa98Sdjl /* reset the result ptr to the original value */ 154cb5caa98Sdjl argp->buf.result = NULL; 155cb5caa98Sdjl 15621b41e80Ssdussud #define printnum(i, num) \ 15721b41e80Ssdussud sprintf(b + (i * 16), "%d", num)) ? b + (i * 16) : "" 158cb5caa98Sdjl 159cb5caa98Sdjl n = snprintf(argp->buf.buffer, argp->buf.buflen, 160cb5caa98Sdjl "%s:%s:%s:%s:%s:%s:%s:%s:%s", sp->sp_namp, 161cb5caa98Sdjl (sp->sp_pwdp ? sp->sp_pwdp : ""), 16221b41e80Ssdussud (sp->sp_lstchg >= 0 && printnum(0, sp->sp_lstchg), 16321b41e80Ssdussud (sp->sp_min >= 0 && printnum(1, sp->sp_min), 16421b41e80Ssdussud (sp->sp_max >= 0 && printnum(2, sp->sp_max), 16521b41e80Ssdussud (sp->sp_warn > 0 && printnum(3, sp->sp_warn), 16621b41e80Ssdussud (sp->sp_inact > 0 && printnum(4, sp->sp_inact), 16721b41e80Ssdussud (sp->sp_expire > 0 && printnum(5, sp->sp_expire), 16821b41e80Ssdussud (sp->sp_flag != 0 && printnum(6, sp->sp_flag)); 169cb5caa98Sdjl 170cb5caa98Sdjl if (n > argp->buf.buflen) 171cb5caa98Sdjl return (NSS_STR_PARSE_ERANGE); 172cb5caa98Sdjl else { 173cb5caa98Sdjl argp->returnlen = n - 1; 174cb5caa98Sdjl return (NSS_SUCCESS); 175cb5caa98Sdjl } 176cb5caa98Sdjl 177cb5caa98Sdjl } else 1787c478bd9Sstevel@tonic-gate return (NSS_STR_PARSE_SUCCESS); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate static compat_backend_op_t shadow_ops[] = { 1827c478bd9Sstevel@tonic-gate _nss_compat_destr, 1837c478bd9Sstevel@tonic-gate _nss_compat_endent, 1847c478bd9Sstevel@tonic-gate _nss_compat_setent, 1857c478bd9Sstevel@tonic-gate _nss_compat_getent, 1867c478bd9Sstevel@tonic-gate getbyname 1877c478bd9Sstevel@tonic-gate }; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1907c478bd9Sstevel@tonic-gate nss_backend_t * 1917c478bd9Sstevel@tonic-gate _nss_compat_shadow_constr(dummy1, dummy2, dummy3) 1927c478bd9Sstevel@tonic-gate const char *dummy1, *dummy2, *dummy3; 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate return (_nss_compat_constr(shadow_ops, 1957c478bd9Sstevel@tonic-gate sizeof (shadow_ops) / sizeof (shadow_ops[0]), 1967c478bd9Sstevel@tonic-gate SHADOW, 1977c478bd9Sstevel@tonic-gate NSS_LINELEN_SHADOW, 1987c478bd9Sstevel@tonic-gate &db_root, 1997c478bd9Sstevel@tonic-gate _nss_initf_shadow_compat, 2007c478bd9Sstevel@tonic-gate 1, 2017c478bd9Sstevel@tonic-gate get_spnamp, 2027c478bd9Sstevel@tonic-gate merge_spents)); 2037c478bd9Sstevel@tonic-gate } 204