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*2b4a7802SBaban Kenkre * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23cb5caa98Sdjl * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate *
257c478bd9Sstevel@tonic-gate * files/getgrent.c -- "files" backend for nsswitch "group" database
267c478bd9Sstevel@tonic-gate */
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate #include <grp.h>
297c478bd9Sstevel@tonic-gate #include <unistd.h> /* for GF_PATH */
30cb5caa98Sdjl #include <stdlib.h> /* for GF_PATH */
317c478bd9Sstevel@tonic-gate #include "files_common.h"
327c478bd9Sstevel@tonic-gate #include <strings.h>
337c478bd9Sstevel@tonic-gate
34cb5caa98Sdjl static uint_t
hash_grname(nss_XbyY_args_t * argp,int keyhash,const char * line,int linelen)35cb5caa98Sdjl hash_grname(nss_XbyY_args_t *argp, int keyhash, const char *line,
36cb5caa98Sdjl int linelen)
377c478bd9Sstevel@tonic-gate {
38cb5caa98Sdjl const char *name;
39cb5caa98Sdjl int namelen, i;
40cb5caa98Sdjl uint_t hash = 0;
417c478bd9Sstevel@tonic-gate
42cb5caa98Sdjl if (keyhash) {
43cb5caa98Sdjl name = argp->key.name;
44cb5caa98Sdjl namelen = strlen(name);
45cb5caa98Sdjl } else {
46cb5caa98Sdjl name = line;
47cb5caa98Sdjl namelen = 0;
48cb5caa98Sdjl while (linelen-- && *line++ != ':')
49cb5caa98Sdjl namelen++;
50cb5caa98Sdjl }
517c478bd9Sstevel@tonic-gate
52cb5caa98Sdjl for (i = 0; i < namelen; i++)
53cb5caa98Sdjl hash = hash * 15 + name[i];
547c478bd9Sstevel@tonic-gate return (hash);
557c478bd9Sstevel@tonic-gate }
567c478bd9Sstevel@tonic-gate
57cb5caa98Sdjl static uint_t
hash_grgid(nss_XbyY_args_t * argp,int keyhash,const char * line,int linelen)58cb5caa98Sdjl hash_grgid(nss_XbyY_args_t *argp, int keyhash, const char *line,
59cb5caa98Sdjl int linelen)
607c478bd9Sstevel@tonic-gate {
61cb5caa98Sdjl uint_t id;
62cb5caa98Sdjl const char *linep, *limit, *end;
63cb5caa98Sdjl
64cb5caa98Sdjl linep = line;
65cb5caa98Sdjl limit = line + linelen;
66cb5caa98Sdjl
67cb5caa98Sdjl if (keyhash)
68cb5caa98Sdjl return ((uint_t)argp->key.gid);
69cb5caa98Sdjl
70*2b4a7802SBaban Kenkre while (linep < limit && *linep++ != ':') /* skip groupname */
71*2b4a7802SBaban Kenkre continue;
72*2b4a7802SBaban Kenkre while (linep < limit && *linep++ != ':') /* skip password */
73*2b4a7802SBaban Kenkre continue;
74cb5caa98Sdjl if (linep == limit)
75cb5caa98Sdjl return (GID_NOBODY);
76cb5caa98Sdjl
77cb5caa98Sdjl /* gid */
78cb5caa98Sdjl end = linep;
79*2b4a7802SBaban Kenkre id = (uint_t)strtoul(linep, (char **)&end, 10);
80cb5caa98Sdjl /* empty gid */
81cb5caa98Sdjl if (linep == end)
82cb5caa98Sdjl return (GID_NOBODY);
83cb5caa98Sdjl
84cb5caa98Sdjl return (id);
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate static files_hash_func hash_gr[2] = { hash_grname, hash_grgid };
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate static files_hash_t hashinfo = {
907c478bd9Sstevel@tonic-gate DEFAULTMUTEX,
917c478bd9Sstevel@tonic-gate sizeof (struct group),
927c478bd9Sstevel@tonic-gate NSS_BUFLEN_GROUP,
937c478bd9Sstevel@tonic-gate 2,
947c478bd9Sstevel@tonic-gate hash_gr
957c478bd9Sstevel@tonic-gate };
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate static int
check_grname(nss_XbyY_args_t * argp,const char * line,int linelen)98cb5caa98Sdjl check_grname(nss_XbyY_args_t *argp, const char *line, int linelen)
997c478bd9Sstevel@tonic-gate {
100cb5caa98Sdjl const char *linep, *limit;
101cb5caa98Sdjl const char *keyp = argp->key.name;
1027c478bd9Sstevel@tonic-gate
103cb5caa98Sdjl linep = line;
104cb5caa98Sdjl limit = line + linelen;
105cb5caa98Sdjl
106cb5caa98Sdjl /* +/- entries valid for compat source only */
107cb5caa98Sdjl if (linelen == 0 || *line == '+' || *line == '-')
1087c478bd9Sstevel@tonic-gate return (0);
109cb5caa98Sdjl while (*keyp && linep < limit && *keyp == *linep) {
110cb5caa98Sdjl keyp++;
111cb5caa98Sdjl linep++;
112cb5caa98Sdjl }
113cb5caa98Sdjl return (linep < limit && *keyp == '\0' && *linep == ':');
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate static nss_status_t
getbyname(be,a)1177c478bd9Sstevel@tonic-gate getbyname(be, a)
1187c478bd9Sstevel@tonic-gate files_backend_ptr_t be;
1197c478bd9Sstevel@tonic-gate void *a;
1207c478bd9Sstevel@tonic-gate {
1217c478bd9Sstevel@tonic-gate return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, check_grname));
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate static int
check_grgid(nss_XbyY_args_t * argp,const char * line,int linelen)125cb5caa98Sdjl check_grgid(nss_XbyY_args_t *argp, const char *line, int linelen)
1267c478bd9Sstevel@tonic-gate {
127cb5caa98Sdjl const char *linep, *limit, *end;
128*2b4a7802SBaban Kenkre ulong_t gr_gid;
1297c478bd9Sstevel@tonic-gate
130cb5caa98Sdjl linep = line;
131cb5caa98Sdjl limit = line + linelen;
132cb5caa98Sdjl
133cb5caa98Sdjl /* +/- entries valid for compat source only */
134cb5caa98Sdjl if (linelen == 0 || *line == '+' || *line == '-')
1357c478bd9Sstevel@tonic-gate return (0);
136cb5caa98Sdjl
137*2b4a7802SBaban Kenkre while (linep < limit && *linep++ != ':') /* skip groupname */
138*2b4a7802SBaban Kenkre continue;
139*2b4a7802SBaban Kenkre while (linep < limit && *linep++ != ':') /* skip password */
140*2b4a7802SBaban Kenkre continue;
141cb5caa98Sdjl if (linep == limit)
142cb5caa98Sdjl return (0);
143cb5caa98Sdjl
144*2b4a7802SBaban Kenkre /* gid */
145cb5caa98Sdjl end = linep;
146*2b4a7802SBaban Kenkre gr_gid = strtoul(linep, (char **)&end, 10);
147cb5caa98Sdjl
148*2b4a7802SBaban Kenkre /* check if gid is empty or overflows */
149*2b4a7802SBaban Kenkre if (linep == end || gr_gid > UINT32_MAX)
150cb5caa98Sdjl return (0);
151cb5caa98Sdjl
152*2b4a7802SBaban Kenkre return ((gid_t)gr_gid == argp->key.gid);
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate static nss_status_t
getbygid(be,a)1567c478bd9Sstevel@tonic-gate getbygid(be, a)
1577c478bd9Sstevel@tonic-gate files_backend_ptr_t be;
1587c478bd9Sstevel@tonic-gate void *a;
1597c478bd9Sstevel@tonic-gate {
160*2b4a7802SBaban Kenkre nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
161*2b4a7802SBaban Kenkre
162*2b4a7802SBaban Kenkre if (argp->key.gid > MAXUID)
163*2b4a7802SBaban Kenkre return (NSS_NOTFOUND);
164*2b4a7802SBaban Kenkre return (_nss_files_XY_hash(be, argp, 0, &hashinfo, 1, check_grgid));
165*2b4a7802SBaban Kenkre }
166*2b4a7802SBaban Kenkre
167*2b4a7802SBaban Kenkre /*
168*2b4a7802SBaban Kenkre * Validates group entry replacing gid > MAXUID by GID_NOBODY.
169*2b4a7802SBaban Kenkre */
170*2b4a7802SBaban Kenkre int
validate_group_ids(char * line,int * linelenp,int buflen,int extra_chars,files_XY_check_func check)171*2b4a7802SBaban Kenkre validate_group_ids(char *line, int *linelenp, int buflen, int extra_chars,
172*2b4a7802SBaban Kenkre files_XY_check_func check)
173*2b4a7802SBaban Kenkre {
174*2b4a7802SBaban Kenkre char *linep, *limit, *gidp;
175*2b4a7802SBaban Kenkre ulong_t gid;
176*2b4a7802SBaban Kenkre int oldgidlen, idlen;
177*2b4a7802SBaban Kenkre int linelen = *linelenp, newlinelen;
178*2b4a7802SBaban Kenkre
179*2b4a7802SBaban Kenkre /*
180*2b4a7802SBaban Kenkre * getbygid() rejects searching by ephemeral gid therefore
181*2b4a7802SBaban Kenkre * no need to validate because the matched entry won't have
182*2b4a7802SBaban Kenkre * an ephemeral gid.
183*2b4a7802SBaban Kenkre */
184*2b4a7802SBaban Kenkre if (check != NULL && check == check_grgid)
185*2b4a7802SBaban Kenkre return (NSS_STR_PARSE_SUCCESS);
186*2b4a7802SBaban Kenkre
187*2b4a7802SBaban Kenkre /* +/- entries valid for compat source only */
188*2b4a7802SBaban Kenkre if (linelen == 0 || *line == '+' || *line == '-')
189*2b4a7802SBaban Kenkre return (NSS_STR_PARSE_SUCCESS);
190*2b4a7802SBaban Kenkre
191*2b4a7802SBaban Kenkre linep = line;
192*2b4a7802SBaban Kenkre limit = line + linelen;
193*2b4a7802SBaban Kenkre
194*2b4a7802SBaban Kenkre while (linep < limit && *linep++ != ':') /* skip groupname */
195*2b4a7802SBaban Kenkre continue;
196*2b4a7802SBaban Kenkre while (linep < limit && *linep++ != ':') /* skip password */
197*2b4a7802SBaban Kenkre continue;
198*2b4a7802SBaban Kenkre if (linep == limit)
199*2b4a7802SBaban Kenkre return (NSS_STR_PARSE_PARSE);
200*2b4a7802SBaban Kenkre
201*2b4a7802SBaban Kenkre gidp = linep;
202*2b4a7802SBaban Kenkre gid = strtoul(gidp, (char **)&linep, 10); /* grab gid */
203*2b4a7802SBaban Kenkre oldgidlen = linep - gidp;
204*2b4a7802SBaban Kenkre if (linep >= limit || oldgidlen == 0)
205*2b4a7802SBaban Kenkre return (NSS_STR_PARSE_PARSE);
206*2b4a7802SBaban Kenkre
207*2b4a7802SBaban Kenkre if (gid <= MAXUID)
208*2b4a7802SBaban Kenkre return (NSS_STR_PARSE_SUCCESS);
209*2b4a7802SBaban Kenkre
210*2b4a7802SBaban Kenkre idlen = snprintf(NULL, 0, "%u", GID_NOBODY);
211*2b4a7802SBaban Kenkre newlinelen = linelen + idlen - oldgidlen;
212*2b4a7802SBaban Kenkre if (newlinelen + extra_chars > buflen)
213*2b4a7802SBaban Kenkre return (NSS_STR_PARSE_ERANGE);
214*2b4a7802SBaban Kenkre
215*2b4a7802SBaban Kenkre (void) bcopy(linep, gidp + idlen, limit - linep + extra_chars);
216*2b4a7802SBaban Kenkre (void) snprintf(gidp, idlen + 1, "%u", GID_NOBODY);
217*2b4a7802SBaban Kenkre *(gidp + idlen) = ':';
218*2b4a7802SBaban Kenkre *linelenp = newlinelen;
219*2b4a7802SBaban Kenkre return (NSS_STR_PARSE_SUCCESS);
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate static nss_status_t
getbymember(be,a)2237c478bd9Sstevel@tonic-gate getbymember(be, a)
2247c478bd9Sstevel@tonic-gate files_backend_ptr_t be;
2257c478bd9Sstevel@tonic-gate void *a;
2267c478bd9Sstevel@tonic-gate {
2277c478bd9Sstevel@tonic-gate struct nss_groupsbymem *argp = (struct nss_groupsbymem *)a;
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate return (_nss_files_do_all(be, argp, argp->username,
2307c478bd9Sstevel@tonic-gate (files_do_all_func_t)argp->process_cstr));
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate static files_backend_op_t group_ops[] = {
2347c478bd9Sstevel@tonic-gate _nss_files_destr,
2357c478bd9Sstevel@tonic-gate _nss_files_endent,
2367c478bd9Sstevel@tonic-gate _nss_files_setent,
2377c478bd9Sstevel@tonic-gate _nss_files_getent_rigid,
2387c478bd9Sstevel@tonic-gate getbyname,
2397c478bd9Sstevel@tonic-gate getbygid,
2407c478bd9Sstevel@tonic-gate getbymember
2417c478bd9Sstevel@tonic-gate };
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2447c478bd9Sstevel@tonic-gate nss_backend_t *
_nss_files_group_constr(dummy1,dummy2,dummy3)2457c478bd9Sstevel@tonic-gate _nss_files_group_constr(dummy1, dummy2, dummy3)
2467c478bd9Sstevel@tonic-gate const char *dummy1, *dummy2, *dummy3;
2477c478bd9Sstevel@tonic-gate {
2487c478bd9Sstevel@tonic-gate return (_nss_files_constr(group_ops,
2497c478bd9Sstevel@tonic-gate sizeof (group_ops) / sizeof (group_ops[0]),
2507c478bd9Sstevel@tonic-gate GF_PATH,
2517c478bd9Sstevel@tonic-gate NSS_LINELEN_GROUP,
2527c478bd9Sstevel@tonic-gate &hashinfo));
2537c478bd9Sstevel@tonic-gate }
254