author | Jon Tibble <meths@btinternet.com> |
Thu, 09 Dec 2010 22:32:39 +0100 | |
changeset 13255 | 4afa820d78b9 |
parent 11411 | c2fe1bf96826 |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
2830 | 5 |
* Common Development and Distribution License (the "License"). |
6 |
* You may not use this file except in compliance with the License. |
|
0 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
3864 | 21 |
|
0 | 22 |
/* |
8765
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
23 |
* Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
0 | 24 |
* Use is subject to license terms. |
25 |
*/ |
|
26 |
||
6812 | 27 |
#include "lint.h" |
2830 | 28 |
#include <mtlib.h> |
0 | 29 |
#include <ctype.h> |
30 |
#include <stdio.h> |
|
31 |
#include <stdlib.h> |
|
32 |
#include <string.h> |
|
33 |
#include <nss_dbdefs.h> |
|
34 |
#include <limits.h> |
|
2830 | 35 |
#include <dlfcn.h> |
36 |
#include <link.h> |
|
37 |
#include <thread.h> |
|
3864 | 38 |
#include <atomic.h> |
2830 | 39 |
/* headers for key2str/str2key routines */ |
40 |
#include <sys/ethernet.h> |
|
41 |
#include <exec_attr.h> |
|
42 |
#include <grp.h> |
|
43 |
||
44 |
/* |
|
45 |
* functions in nss_dbdefs.c deal more with the mechanics of |
|
46 |
* the data structures like nss_XbyY_args_t and the interaction |
|
47 |
* with the packed buffers etc. versus the mechanics of the |
|
48 |
* actual policy component operations such as nss_search sequencing. |
|
49 |
*/ |
|
0 | 50 |
|
51 |
/* |
|
52 |
* ALIGN? is there an official definition of this? |
|
53 |
* We use sizeof(long) to cover what we want |
|
54 |
* for both the 32-bit world and 64-bit world. |
|
55 |
*/ |
|
56 |
||
57 |
#define ALIGN(x) ((((long)(x)) + sizeof (long) - 1) & ~(sizeof (long) - 1)) |
|
58 |
||
59 |
nss_XbyY_buf_t * |
|
60 |
_nss_XbyY_buf_alloc(int struct_size, int buffer_size) |
|
61 |
{ |
|
62 |
nss_XbyY_buf_t *b; |
|
63 |
||
64 |
/* Use one malloc for dbargs, result struct and buffer */ |
|
65 |
b = (nss_XbyY_buf_t *) |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
66 |
malloc(ALIGN(sizeof (*b)) + struct_size + buffer_size); |
0 | 67 |
if (b == 0) { |
68 |
return (0); |
|
69 |
} |
|
70 |
b->result = (void *)ALIGN(&b[1]); |
|
71 |
b->buffer = (char *)(b->result) + struct_size; |
|
72 |
b->buflen = buffer_size; |
|
73 |
return (b); |
|
74 |
} |
|
75 |
||
76 |
void |
|
77 |
_nss_XbyY_buf_free(nss_XbyY_buf_t *b) |
|
78 |
{ |
|
79 |
if (b != 0) { |
|
80 |
free(b); |
|
81 |
} |
|
82 |
} |
|
83 |
||
84 |
/* === Comment: used by fget{gr,pw,sp}ent */ |
|
85 |
/* ==== Should do ye olde syslog()ing of suspiciously long lines */ |
|
86 |
||
87 |
void |
|
88 |
_nss_XbyY_fgets(FILE *f, nss_XbyY_args_t *b) |
|
89 |
{ |
|
90 |
char buf[LINE_MAX]; |
|
91 |
int len, parsestat; |
|
92 |
||
93 |
if (fgets(buf, LINE_MAX, f) == 0) { |
|
94 |
/* End of file */ |
|
95 |
b->returnval = 0; |
|
96 |
b->erange = 0; |
|
97 |
return; |
|
98 |
} |
|
99 |
len = (int)strlen(buf); |
|
100 |
/* len >= 0 (otherwise we would have got EOF) */ |
|
101 |
if (buf[len - 1] != '\n') { |
|
102 |
if ((len + 1) == LINE_MAX) { |
|
103 |
/* Line too long for buffer; too bad */ |
|
104 |
while (fgets(buf, LINE_MAX, f) != 0 && |
|
105 |
buf[strlen(buf) - 1] != '\n') { |
|
106 |
; |
|
107 |
} |
|
108 |
b->returnval = 0; |
|
109 |
b->erange = 1; |
|
110 |
return; |
|
111 |
} |
|
112 |
/* case where the file is not terminated with a Newline */ |
|
113 |
len++; |
|
114 |
} |
|
115 |
parsestat = (*b->str2ent)(buf, (len - 1), b->buf.result, b->buf.buffer, |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
116 |
b->buf.buflen); |
0 | 117 |
if (parsestat == NSS_STR_PARSE_ERANGE) { |
118 |
b->returnval = 0; |
|
119 |
b->erange = 1; |
|
120 |
} else if (parsestat == NSS_STR_PARSE_SUCCESS) { |
|
121 |
b->returnval = b->buf.result; |
|
122 |
} |
|
123 |
} |
|
124 |
||
125 |
/* |
|
126 |
* parse the aliases string into the buffer and if successful return |
|
127 |
* a char ** pointer to the beginning of the aliases. |
|
128 |
* |
|
129 |
* CAUTION: (instr, instr+lenstr) and (buffer, buffer+buflen) are |
|
130 |
* non-intersecting memory areas. Since this is an internal interface, |
|
131 |
* we should be able to live with that. |
|
132 |
*/ |
|
133 |
char ** |
|
134 |
_nss_netdb_aliases(const char *instr, int lenstr, char *buffer, int buflen) |
|
135 |
/* "instr" is the beginning of the aliases string */ |
|
136 |
/* "buffer" has the return val for success */ |
|
137 |
/* "buflen" is the length of the buffer available for aliases */ |
|
138 |
{ |
|
139 |
/* |
|
140 |
* Build the alias-list in the start of the buffer, and copy |
|
141 |
* the strings to the end of the buffer. |
|
142 |
*/ |
|
143 |
const char |
|
144 |
*instr_limit = instr + lenstr; |
|
145 |
char *copyptr = buffer + buflen; |
|
146 |
char **aliasp = (char **)ROUND_UP(buffer, sizeof (*aliasp)); |
|
147 |
char **alias_start = aliasp; |
|
148 |
int nstrings = 0; |
|
149 |
||
150 |
for (;;) { |
|
151 |
const char *str_start; |
|
152 |
size_t str_len; |
|
153 |
||
154 |
while (instr < instr_limit && isspace(*instr)) { |
|
155 |
instr++; |
|
156 |
} |
|
157 |
if (instr >= instr_limit || *instr == '#') { |
|
158 |
break; |
|
159 |
} |
|
160 |
str_start = instr; |
|
161 |
while (instr < instr_limit && !isspace(*instr)) { |
|
162 |
instr++; |
|
163 |
} |
|
164 |
||
165 |
++nstrings; |
|
166 |
||
167 |
str_len = instr - str_start; |
|
168 |
copyptr -= str_len + 1; |
|
169 |
if (copyptr <= (char *)(&aliasp[nstrings + 1])) { |
|
170 |
/* Has to be room for the pointer to */ |
|
171 |
/* the alias we're about to add, */ |
|
172 |
/* as well as the final NULL ptr. */ |
|
173 |
return (0); |
|
174 |
} |
|
175 |
*aliasp++ = copyptr; |
|
176 |
(void) memcpy(copyptr, str_start, str_len); |
|
177 |
copyptr[str_len] = '\0'; |
|
178 |
} |
|
179 |
*aliasp++ = 0; |
|
180 |
return (alias_start); |
|
181 |
} |
|
2830 | 182 |
|
183 |
||
3099
df972f671b58
6462185 /etc/hosts parsing is still retarded and broken
michen
parents:
2830
diff
changeset
|
184 |
extern nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *); |
df972f671b58
6462185 /etc/hosts parsing is still retarded and broken
michen
parents:
2830
diff
changeset
|
185 |
|
2830 | 186 |
/* |
187 |
* pack well known getXbyY keys to packed buffer prior to the door_call |
|
188 |
* to nscd. Some consideration is given to ordering the tests based on |
|
189 |
* usage. Note: buf is nssuint_t aligned. |
|
190 |
*/ |
|
191 |
||
192 |
typedef struct { |
|
193 |
const char *name; /* NSS_DBNAM_* */ |
|
194 |
const char *defconf; /* NSS_DEFCONF_* */ |
|
195 |
const char *initfn; /* init function name */ |
|
196 |
const char *strfn; /* str2X function name */ |
|
197 |
const char *cstrfn; /* cstr2X function name */ |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
198 |
void *initfnp; /* init function pointer */ |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
199 |
void *strfnp; /* str2X function pointer */ |
2830 | 200 |
uint32_t dbop; /* NSS_DBOP_* */ |
201 |
const char *tostr; /* key2str cvt str */ |
|
202 |
} getXbyY_to_dbop_t; |
|
203 |
||
204 |
#define NSS_MK_GETXYDBOP(x, y, f, e) \ |
|
205 |
{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, "str2" f, \ |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
206 |
NULL, NULL, NULL, NSS_DBOP_##x##_##y, (e) } |
2830 | 207 |
|
208 |
#define NSS_MK_GETXYDBOPA(x, a, f, e) \ |
|
209 |
{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, "str2" f, \ |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
210 |
NULL, NULL, NULL, NSS_DBOP_##a, (e) } |
2830 | 211 |
|
212 |
#define NSS_MK_GETXYDBOPB(x, b, a, f, s, e) \ |
|
213 |
{ NSS_DBNAM_##x, NSS_DEFCONF_##b, "_nss_initf_" f, s, \ |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
214 |
NULL, NULL, NULL, NSS_DBOP_##a, (e) } |
2830 | 215 |
|
216 |
#define NSS_MK_GETXYDBOPC(x, a, f, s, e) \ |
|
217 |
{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, s, \ |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
218 |
NULL, NULL, NULL, NSS_DBOP_##x##_##a, (e) } |
2830 | 219 |
|
220 |
#define NSS_MK_GETXYDBOPD(x, y, i, f, e) \ |
|
221 |
{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" i, "str2" f, \ |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
222 |
NULL, NULL, NULL, NSS_DBOP_##x##_##y, (e) } |
2830 | 223 |
|
224 |
#define NSS_MK_GETXYDBOPCSTR(x, a, f, s, e) \ |
|
225 |
{ NSS_DBNAM_##x, NSS_DEFCONF_##x, "_nss_initf_" f, s, \ |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
226 |
"process_cstr", NULL, NULL, NSS_DBOP_##x##_##a, (e) } |
2830 | 227 |
|
228 |
/* |
|
229 |
* The getXbyY_to_dbop structure is hashed on first call in order to |
|
230 |
* reduce the search time for the well known getXbyY operations. |
|
231 |
* A binary search was not fast enough. There were on average |
|
232 |
* 3-4 tests (strcmps) per getXbyY call. |
|
233 |
* |
|
234 |
* DBOP_PRIME_HASH must be a prime number (reasonably small) but that |
|
235 |
* is sufficient to uniquely map the entries in the following table |
|
236 |
* without collision. |
|
237 |
* |
|
238 |
* The DBOP_PRIME_HASH was selected as the smallest hash value |
|
239 |
* for this table without collisions. Changing this table WILL |
|
240 |
* necessitate re-testing for possible collisions. |
|
241 |
*/ |
|
242 |
||
8765
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
243 |
#define DBOP_PRIME_HASH 227 |
2830 | 244 |
#define DBOP_HASH_TAG 0xf0000000 |
245 |
static int getXbyYdbopHASH[DBOP_PRIME_HASH] = { 0 }; |
|
246 |
static mutex_t getXbydbop_hash_lock = DEFAULTMUTEX; |
|
247 |
static int getXbyYdbop_hashed = 0; |
|
248 |
||
8765
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
249 |
/* |
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
250 |
* If the size of getXbyY_to_dbop[] is changed then hash function must be |
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
251 |
* corrected to be without collisions in nss_dbop_search(). |
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
252 |
*/ |
2830 | 253 |
static getXbyY_to_dbop_t getXbyY_to_dbop[] = { |
254 |
/* NSS_MK_GETXYDBOP(ALIASES, ?, ?), */ |
|
255 |
NSS_MK_GETXYDBOPD(AUDITUSER, BYNAME, "auuser", "audituser", "n"), |
|
256 |
NSS_MK_GETXYDBOP(AUTHATTR, BYNAME, "authattr", "n"), |
|
257 |
/* NSS_MK_GETXYDBOP(AUTOMOUNT, ?, ?), */ |
|
258 |
NSS_MK_GETXYDBOP(BOOTPARAMS, BYNAME, "bootparams", "n"), |
|
259 |
NSS_MK_GETXYDBOPC(ETHERS, HOSTTON, "ethers", "str2ether", "n"), |
|
260 |
NSS_MK_GETXYDBOPC(ETHERS, NTOHOST, "ethers", "str2ether", "e"), |
|
261 |
NSS_MK_GETXYDBOP(EXECATTR, BYNAME, "execattr", "A"), |
|
262 |
NSS_MK_GETXYDBOP(EXECATTR, BYID, "execattr", "A"), |
|
263 |
NSS_MK_GETXYDBOP(EXECATTR, BYNAMEID, "execattr", "A"), |
|
264 |
NSS_MK_GETXYDBOP(GROUP, BYNAME, "group", "n"), |
|
265 |
NSS_MK_GETXYDBOP(GROUP, BYGID, "group", "g"), |
|
266 |
NSS_MK_GETXYDBOPCSTR(GROUP, BYMEMBER, "group", "str2group", "I"), |
|
267 |
NSS_MK_GETXYDBOPC(HOSTS, BYNAME, "hosts", "str2hostent", "n"), |
|
268 |
NSS_MK_GETXYDBOPC(HOSTS, BYADDR, "hosts", "str2hostent", "h"), |
|
269 |
NSS_MK_GETXYDBOPC(IPNODES, BYNAME, "ipnodes", "str2hostent", "i"), |
|
270 |
NSS_MK_GETXYDBOPC(IPNODES, BYADDR, "ipnodes", "str2hostent", "h"), |
|
271 |
NSS_MK_GETXYDBOP(NETGROUP, IN, "netgroup", "t"), |
|
272 |
NSS_MK_GETXYDBOP(NETGROUP, SET, "netgroup", "T"), |
|
273 |
NSS_MK_GETXYDBOPC(NETMASKS, BYNET, "netmasks", "str2addr", "n"), |
|
274 |
NSS_MK_GETXYDBOPC(NETWORKS, BYNAME, "net", "str2netent", "n"), |
|
275 |
NSS_MK_GETXYDBOPC(NETWORKS, BYADDR, "net", "str2netent", "a"), |
|
276 |
NSS_MK_GETXYDBOP(PASSWD, BYNAME, "passwd", "n"), |
|
277 |
NSS_MK_GETXYDBOP(PASSWD, BYUID, "passwd", "u"), |
|
278 |
NSS_MK_GETXYDBOP(PRINTERS, BYNAME, "printers", "n"), |
|
279 |
NSS_MK_GETXYDBOP(PROFATTR, BYNAME, "profattr", "n"), |
|
280 |
NSS_MK_GETXYDBOP(PROJECT, BYNAME, "project", "n"), |
|
281 |
NSS_MK_GETXYDBOP(PROJECT, BYID, "project", "p"), |
|
282 |
NSS_MK_GETXYDBOPC(PROTOCOLS, BYNAME, "proto", "str2protoent", "n"), |
|
283 |
NSS_MK_GETXYDBOPC(PROTOCOLS, BYNUMBER, "proto", "str2protoent", "N"), |
|
284 |
NSS_MK_GETXYDBOPA(PUBLICKEY, KEYS_BYNAME, "publickey", "k"), |
|
285 |
NSS_MK_GETXYDBOPC(RPC, BYNAME, "rpc", "str2rpcent", "n"), |
|
286 |
NSS_MK_GETXYDBOPC(RPC, BYNUMBER, "rpc", "str2rpcent", "N"), |
|
287 |
NSS_MK_GETXYDBOPC(SERVICES, BYNAME, "services", "str2servent", "s"), |
|
288 |
NSS_MK_GETXYDBOPC(SERVICES, BYPORT, "services", "str2servent", "S"), |
|
289 |
NSS_MK_GETXYDBOPB(SHADOW, PASSWD, PASSWD_BYNAME, "shadow", |
|
290 |
"str2spwd", "n"), |
|
291 |
NSS_MK_GETXYDBOPC(TSOL_RH, BYADDR, "tsol_rh", "str_to_rhstr", "h"), |
|
292 |
NSS_MK_GETXYDBOPC(TSOL_TP, BYNAME, "tsol_tp", "str_to_tpstr", "n"), |
|
293 |
NSS_MK_GETXYDBOPC(TSOL_ZC, BYNAME, "tsol_zc", "str_to_zcstr", "n"), |
|
294 |
NSS_MK_GETXYDBOP(USERATTR, BYNAME, "userattr", "n"), |
|
295 |
}; |
|
296 |
||
297 |
static int |
|
298 |
nss_dbop_search(const char *name, uint32_t dbop) |
|
299 |
{ |
|
300 |
getXbyY_to_dbop_t *hptr; |
|
301 |
int count = (sizeof (getXbyY_to_dbop) / sizeof (getXbyY_to_dbop_t)); |
|
302 |
uint32_t hval, g; |
|
303 |
const char *cp; |
|
304 |
int i, idx; |
|
8765
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
305 |
static const uint32_t hbits_tst = 0xf0000000; |
2830 | 306 |
|
307 |
/* Uses a table size is known to have no collisions */ |
|
308 |
if (getXbyYdbop_hashed == 0) { |
|
309 |
lmutex_lock(&getXbydbop_hash_lock); |
|
310 |
if (getXbyYdbop_hashed == 0) { |
|
311 |
for (i = 0; i < count; i++) { |
|
312 |
cp = getXbyY_to_dbop[i].name; |
|
313 |
hval = 0; |
|
314 |
while (*cp) { |
|
315 |
hval = (hval << 4) + *cp++; |
|
8765
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
316 |
if ((g = (hval & hbits_tst)) != 0) |
2830 | 317 |
hval ^= g >> 24; |
318 |
hval &= ~g; |
|
319 |
} |
|
320 |
hval += getXbyY_to_dbop[i].dbop; |
|
321 |
hval %= DBOP_PRIME_HASH; |
|
322 |
if (getXbyYdbopHASH[hval] != 0) { |
|
323 |
/* hash table collision-see above */ |
|
324 |
lmutex_unlock(&getXbydbop_hash_lock); |
|
325 |
return (-1); |
|
326 |
} |
|
327 |
getXbyYdbopHASH[hval] = i | DBOP_HASH_TAG; |
|
328 |
} |
|
3864 | 329 |
membar_producer(); |
2830 | 330 |
getXbyYdbop_hashed = 1; |
331 |
} |
|
332 |
lmutex_unlock(&getXbydbop_hash_lock); |
|
333 |
} |
|
3864 | 334 |
membar_consumer(); |
2830 | 335 |
cp = name; |
336 |
hval = 0; |
|
337 |
while (*cp) { |
|
338 |
hval = (hval << 4) + *cp++; |
|
8765
06531078004e
6742433 nss_dbddefs contains literals overflow
Milan Jurik <Milan.Jurik@Sun.COM>
parents:
6812
diff
changeset
|
339 |
if ((g = (hval & hbits_tst)) != 0) |
2830 | 340 |
hval ^= g >> 24; |
341 |
hval &= ~g; |
|
342 |
} |
|
343 |
hval += dbop; |
|
344 |
hval %= DBOP_PRIME_HASH; |
|
345 |
idx = getXbyYdbopHASH[hval]; |
|
346 |
if ((idx & DBOP_HASH_TAG) != DBOP_HASH_TAG) |
|
347 |
return (-1); |
|
348 |
idx &= ~DBOP_HASH_TAG; |
|
349 |
if (idx >= count) |
|
350 |
return (-1); |
|
351 |
hptr = &getXbyY_to_dbop[idx]; |
|
352 |
if (hptr->dbop != dbop || strcmp(name, hptr->name) != 0) |
|
353 |
return (-1); |
|
354 |
return (idx); |
|
355 |
} |
|
356 |
||
357 |
/* |
|
358 |
* nss_pack_key2str |
|
359 |
* Private key to string packing function for getXbyY routines |
|
360 |
* This routine performs a printf like parse over the argument |
|
361 |
* key, given a string of items to pack and assembles the key in |
|
362 |
* the packed structure. This routine is called (currently) by |
|
363 |
* nss_default_key2str, but will be used by other external |
|
364 |
* APIs in the future. |
|
365 |
* |
|
366 |
* buffer - Start of the key buffer location [in packed buffer] |
|
367 |
* length - Length of key buffer component |
|
368 |
* Key offsets are relative to start of key buffer location. |
|
369 |
* |
|
370 |
* Pack fields Key |
|
371 |
* key.name n |
|
372 |
* key.number N |
|
373 |
* key.uid u |
|
374 |
* key.gid g |
|
375 |
* key.hostaddr h |
|
376 |
* key.ipnode i |
|
377 |
* key.projid p |
|
378 |
* key.serv(name) s |
|
379 |
* key.serv(port) S |
|
380 |
* key.ether e |
|
381 |
* key.pkey k |
|
382 |
* key.netaddr a |
|
383 |
* key.attrp A |
|
384 |
* groupsbymember I |
|
385 |
* innetgr_args t |
|
386 |
* setnetgr_args T |
|
387 |
*/ |
|
388 |
||
389 |
/*ARGSUSED*/ |
|
390 |
static nss_status_t |
|
391 |
nss_pack_key2str(void *buffer, size_t length, nss_XbyY_args_t *arg, |
|
392 |
const char *dbname, int dbop, size_t *rlen, const char *typestr) |
|
393 |
{ |
|
394 |
int i, j; |
|
395 |
size_t len, len2, len3, len4, len5, slop; |
|
396 |
nssuint_t *uptr, offv, offc; |
|
397 |
struct nss_setnetgrent_args *sng; |
|
398 |
struct nss_innetgr_args *ing; |
|
399 |
struct nss_groupsbymem *gbm; |
|
400 |
char **cv, *dptr; |
|
401 |
nss_pnetgr_t *pptr; |
|
402 |
_priv_execattr *pe; |
|
403 |
||
404 |
if (buffer == NULL || length == 0 || arg == NULL || |
|
405 |
dbname == NULL || rlen == NULL || typestr == NULL) |
|
406 |
return (NSS_ERROR); |
|
407 |
||
408 |
while (typestr && *typestr) { |
|
409 |
switch (*typestr++) { |
|
410 |
case 'n': |
|
411 |
if (arg->key.name == NULL) |
|
412 |
return (NSS_NOTFOUND); |
|
413 |
len = strlen(arg->key.name) + 1; |
|
414 |
if (len >= length) |
|
415 |
return (NSS_ERROR); |
|
416 |
(void) strlcpy(buffer, arg->key.name, len); |
|
417 |
*rlen = len; |
|
418 |
break; |
|
419 |
case 'N': |
|
420 |
len = sizeof (nssuint_t); |
|
421 |
if (len >= length) |
|
422 |
return (NSS_ERROR); |
|
423 |
*(nssuint_t *)buffer = (nssuint_t)arg->key.number; |
|
424 |
*rlen = len; |
|
425 |
break; |
|
426 |
case 'u': |
|
427 |
len = sizeof (nssuint_t); |
|
428 |
if (len >= length) |
|
429 |
return (NSS_ERROR); |
|
430 |
*(nssuint_t *)buffer = (nssuint_t)arg->key.uid; |
|
431 |
*rlen = len; |
|
432 |
break; |
|
433 |
case 'g': |
|
434 |
len = sizeof (nssuint_t); |
|
435 |
if (len >= length) |
|
436 |
return (NSS_ERROR); |
|
437 |
*(nssuint_t *)buffer = (nssuint_t)arg->key.gid; |
|
438 |
*rlen = len; |
|
439 |
break; |
|
440 |
case 'h': |
|
441 |
if (arg->key.hostaddr.addr == NULL) |
|
442 |
return (-1); |
|
443 |
len = arg->key.hostaddr.len; |
|
444 |
len = ROUND_UP(len, sizeof (nssuint_t)); |
|
445 |
len2 = (sizeof (nssuint_t) * 2) + len; |
|
446 |
if (len2 >= length) |
|
447 |
return (NSS_ERROR); |
|
448 |
*(nssuint_t *)buffer = |
|
449 |
(nssuint_t)arg->key.hostaddr.len; |
|
450 |
buffer = (void *)((char *)buffer + sizeof (nssuint_t)); |
|
451 |
*(nssuint_t *)buffer = |
|
452 |
(nssuint_t)arg->key.hostaddr.type; |
|
453 |
buffer = (void *)((char *)buffer + sizeof (nssuint_t)); |
|
454 |
(void) memcpy(buffer, arg->key.hostaddr.addr, |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
455 |
arg->key.hostaddr.len); |
2830 | 456 |
*rlen = len2; |
457 |
break; |
|
458 |
case 'i': |
|
459 |
if (arg->key.ipnode.name == NULL) |
|
460 |
return (NSS_NOTFOUND); |
|
461 |
len = strlen(arg->key.ipnode.name) + 1; |
|
462 |
len = ROUND_UP(len, sizeof (nssuint_t)); |
|
463 |
len2 = (sizeof (nssuint_t) * 2) + len; |
|
464 |
if (len2 >= length) |
|
465 |
return (NSS_ERROR); |
|
466 |
*(nssuint_t *)buffer = |
|
467 |
(nssuint_t)arg->key.ipnode.af_family; |
|
468 |
buffer = (void *)((char *)buffer + sizeof (nssuint_t)); |
|
469 |
*(nssuint_t *)buffer = |
|
470 |
(nssuint_t)arg->key.ipnode.flags; |
|
471 |
buffer = (void *)((char *)buffer + sizeof (nssuint_t)); |
|
472 |
(void) strlcpy(buffer, arg->key.ipnode.name, len); |
|
473 |
*rlen = len2; |
|
474 |
break; |
|
475 |
case 'p': |
|
476 |
len = sizeof (nssuint_t); |
|
477 |
if (len >= length) |
|
478 |
return (NSS_ERROR); |
|
479 |
*(nssuint_t *)buffer = (nssuint_t)arg->key.projid; |
|
480 |
*rlen = len; |
|
481 |
break; |
|
482 |
case 's': |
|
483 |
if (arg->key.serv.serv.name == NULL) |
|
484 |
return (NSS_NOTFOUND); |
|
485 |
len = strlen(arg->key.serv.serv.name) + 1; |
|
486 |
len2 = 1; |
|
487 |
if (arg->key.serv.proto != NULL) |
|
488 |
len2 += strlen(arg->key.serv.proto); |
|
489 |
len3 = len + len2; |
|
490 |
len3 = ROUND_UP(len3, sizeof (nssuint_t)); |
|
491 |
if (len3 >= length) |
|
492 |
return (NSS_ERROR); |
|
493 |
(void) strlcpy(buffer, arg->key.serv.serv.name, len); |
|
494 |
buffer = (void *)((char *)buffer + len); |
|
495 |
if (len2 > 1) |
|
496 |
(void) strlcpy(buffer, arg->key.serv.proto, |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
497 |
len2); |
2830 | 498 |
else |
499 |
*(char *)buffer = '\0'; |
|
500 |
*rlen = len3; |
|
501 |
break; |
|
502 |
case 'S': |
|
503 |
len2 = 0; |
|
504 |
if (arg->key.serv.proto != NULL) |
|
505 |
len2 = strlen(arg->key.serv.proto) + 1; |
|
506 |
len = sizeof (nssuint_t) + len2; |
|
507 |
if (len >= length) |
|
508 |
return (NSS_ERROR); |
|
509 |
uptr = (nssuint_t *)buffer; |
|
510 |
*uptr++ = (nssuint_t)arg->key.serv.serv.port; |
|
511 |
if (len2) { |
|
512 |
(void) strlcpy((char *)uptr, |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
513 |
arg->key.serv.proto, len2); |
2830 | 514 |
} |
515 |
*rlen = len; |
|
516 |
break; |
|
517 |
case 'e': |
|
518 |
if (arg->key.ether == NULL) |
|
519 |
return (NSS_NOTFOUND); |
|
520 |
len = sizeof (struct ether_addr); |
|
521 |
len = ROUND_UP(len, sizeof (nssuint_t)); |
|
522 |
if (len >= length) |
|
523 |
return (NSS_ERROR); |
|
524 |
*(struct ether_addr *)buffer = |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
525 |
*(struct ether_addr *)arg->key.ether; |
2830 | 526 |
*rlen = len; |
527 |
break; |
|
528 |
case 'k': |
|
529 |
if (arg->key.pkey.name == NULL || |
|
530 |
arg->key.pkey.keytype == NULL) |
|
531 |
return (NSS_NOTFOUND); |
|
532 |
len = strlen(arg->key.pkey.name) + 1; |
|
533 |
len2 = strlen(arg->key.pkey.keytype) + 1; |
|
534 |
len3 = len + len2; |
|
535 |
len3 = ROUND_UP(len3, sizeof (nssuint_t)); |
|
536 |
if (len3 >= length) |
|
537 |
return (NSS_ERROR); |
|
538 |
(void) strlcpy(buffer, arg->key.pkey.name, len); |
|
539 |
buffer = (void *)((char *)buffer + len); |
|
540 |
(void) strlcpy(buffer, arg->key.pkey.keytype, len2); |
|
541 |
*rlen = len3; |
|
542 |
break; |
|
543 |
case 'a': |
|
544 |
uptr = (nssuint_t *)buffer; |
|
545 |
len = sizeof (nssuint_t) * 2; |
|
546 |
if (len >= length) |
|
547 |
return (NSS_ERROR); |
|
548 |
*uptr++ = (nssuint_t)arg->key.netaddr.net; |
|
549 |
*uptr++ = (nssuint_t)arg->key.netaddr.type; |
|
550 |
*rlen = len; |
|
551 |
break; |
|
552 |
case 'A': |
|
553 |
pe = (_priv_execattr *)(arg->key.attrp); |
|
554 |
if (pe == NULL) |
|
555 |
return (NSS_NOTFOUND); |
|
556 |
/* for search flag */ |
|
557 |
len = sizeof (nssuint_t); |
|
558 |
/* for sizeof (_priv_execattr) static buffer */ |
|
559 |
/* Plus lots of slop just in case... */ |
|
560 |
slop = sizeof (nssuint_t) * 16; |
|
561 |
len += slop; |
|
562 |
||
563 |
len2 = len3 = len4 = len5 = 1; |
|
564 |
if (pe->name != NULL) |
|
565 |
len2 = strlen(pe->name) + 1; |
|
566 |
if (pe->type != NULL) |
|
567 |
len3 = strlen(pe->type) + 1; |
|
568 |
if (pe->id != NULL) |
|
569 |
len4 = strlen(pe->id) + 1; |
|
570 |
if (pe->policy != NULL) |
|
571 |
len5 = strlen(pe->policy) + 1; |
|
572 |
/* head_exec, prev_exec - are client side only... */ |
|
573 |
len += len2 + len3 + len4 + len5; |
|
574 |
len = ROUND_UP(len, sizeof (nssuint_t)); |
|
575 |
if (len >= length) |
|
576 |
return (NSS_ERROR); |
|
577 |
(void) memset((void *)buffer, 0, slop); |
|
578 |
uptr = (nssuint_t *)((void *)((char *)buffer + slop)); |
|
579 |
*uptr++ = (nssuint_t)pe->search_flag; |
|
580 |
dptr = (char *)uptr; |
|
581 |
if (len2 == 1) |
|
582 |
*dptr++ = '\0'; |
|
583 |
else { |
|
584 |
(void) strlcpy(dptr, pe->name, len2); |
|
585 |
dptr += len2; |
|
586 |
} |
|
587 |
if (len3 == 1) |
|
588 |
*dptr++ = '\0'; |
|
589 |
else { |
|
590 |
(void) strlcpy(dptr, pe->type, len3); |
|
591 |
dptr += len3; |
|
592 |
} |
|
593 |
if (len4 == 1) |
|
594 |
*dptr++ = '\0'; |
|
595 |
else { |
|
596 |
(void) strlcpy(dptr, pe->id, len4); |
|
597 |
dptr += len4; |
|
598 |
} |
|
599 |
if (len5 == 1) |
|
600 |
*dptr++ = '\0'; |
|
601 |
else |
|
602 |
(void) strlcpy(dptr, pe->policy, len5); |
|
603 |
*rlen = len; |
|
604 |
break; |
|
605 |
case 'I': |
|
606 |
gbm = (struct nss_groupsbymem *)arg; |
|
607 |
if (gbm->username == NULL) |
|
608 |
return (NSS_NOTFOUND); |
|
609 |
len = strlen(gbm->username) + 1; |
|
610 |
len2 = sizeof (nssuint_t) * 4; |
|
611 |
len2 += ROUND_UP(len, sizeof (nssuint_t)); |
|
612 |
if (len2 >= length) |
|
613 |
return (NSS_ERROR); |
|
614 |
uptr = (nssuint_t *)buffer; |
|
615 |
*uptr++ = (nssuint_t)gbm->force_slow_way; |
|
616 |
*uptr++ = (nssuint_t)gbm->maxgids; |
|
617 |
*uptr++ = (nssuint_t)gbm->numgids; |
|
618 |
if (gbm->numgids == 1) { |
|
619 |
*uptr++ = (nssuint_t)gbm->gid_array[0]; |
|
620 |
} else { |
|
621 |
*uptr++ = (nssuint_t)0; |
|
622 |
} |
|
623 |
(void) strlcpy((void *)uptr, gbm->username, len); |
|
624 |
*rlen = len2; |
|
625 |
break; |
|
626 |
case 't': |
|
627 |
pptr = (nss_pnetgr_t *)buffer; |
|
628 |
ing = (struct nss_innetgr_args *)arg; |
|
629 |
len = sizeof (nss_pnetgr_t); |
|
630 |
len2 = ing->arg[NSS_NETGR_MACHINE].argc + |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
631 |
ing->arg[NSS_NETGR_USER].argc + |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
632 |
ing->arg[NSS_NETGR_DOMAIN].argc + |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
633 |
ing->groups.argc; |
2830 | 634 |
len2 *= sizeof (nssuint_t); |
635 |
len3 = 0; |
|
636 |
for (j = 0; j < NSS_NETGR_N; j++) { |
|
637 |
cv = ing->arg[j].argv; |
|
638 |
for (i = ing->arg[j].argc; --i >= 0; ) { |
|
639 |
if (*cv) |
|
640 |
len3 += strlen(*cv++) + 1; |
|
641 |
} |
|
642 |
} |
|
643 |
cv = ing->groups.argv; |
|
644 |
for (i = ing->groups.argc; --i >= 0; ) { |
|
645 |
if (*cv) |
|
646 |
len3 += strlen(*cv++) + 1; |
|
647 |
} |
|
648 |
len3 = ROUND_UP(len3, sizeof (nssuint_t)); |
|
649 |
/* |
|
650 |
* Double argv space. Reason: |
|
651 |
* First 1/2 offsets |
|
652 |
* Second 1/2 for client side pointer arrays |
|
653 |
* resolves malloc/free issues with unpacked argvs |
|
654 |
*/ |
|
655 |
if ((len + (len2 << 1) + len3) >= length) |
|
656 |
return (NSS_ERROR); |
|
657 |
*rlen = len + (len2 << 1) + len3; |
|
658 |
||
659 |
pptr->machine_argc = ing->arg[NSS_NETGR_MACHINE].argc; |
|
660 |
pptr->user_argc = ing->arg[NSS_NETGR_USER].argc; |
|
661 |
pptr->domain_argc = ing->arg[NSS_NETGR_DOMAIN].argc; |
|
662 |
pptr->groups_argc = ing->groups.argc; |
|
663 |
offv = len; |
|
664 |
uptr = (nssuint_t *)((void *)((char *)buffer + offv)); |
|
665 |
offc = len + (len2 << 1); |
|
666 |
dptr = (char *)buffer + offc; |
|
667 |
if (pptr->machine_argc == 0) { |
|
668 |
pptr->machine_offv = (nssuint_t)0; |
|
669 |
} else { |
|
670 |
pptr->machine_offv = offv; |
|
671 |
cv = ing->arg[NSS_NETGR_MACHINE].argv; |
|
672 |
i = pptr->machine_argc; |
|
673 |
offv += sizeof (nssuint_t) * i; |
|
674 |
for (; --i >= 0; ) { |
|
675 |
*uptr++ = offc; |
|
676 |
len3 = strlen(*cv) + 1; |
|
677 |
(void) strlcpy(dptr, *cv++, len3); |
|
678 |
offc += len3; |
|
679 |
dptr += len3; |
|
680 |
} |
|
681 |
} |
|
682 |
if (pptr->user_argc == 0) { |
|
683 |
pptr->user_offv = (nssuint_t)0; |
|
684 |
} else { |
|
685 |
pptr->user_offv = offv; |
|
686 |
cv = ing->arg[NSS_NETGR_USER].argv; |
|
687 |
i = pptr->user_argc; |
|
688 |
offv += sizeof (nssuint_t) * i; |
|
689 |
for (; --i >= 0; ) { |
|
690 |
*uptr++ = offc; |
|
691 |
len3 = strlen(*cv) + 1; |
|
692 |
(void) strlcpy(dptr, *cv++, len3); |
|
693 |
offc += len3; |
|
694 |
dptr += len3; |
|
695 |
} |
|
696 |
} |
|
697 |
if (pptr->domain_argc == 0) { |
|
698 |
pptr->domain_offv = (nssuint_t)0; |
|
699 |
} else { |
|
700 |
pptr->domain_offv = offv; |
|
701 |
cv = ing->arg[NSS_NETGR_DOMAIN].argv; |
|
702 |
i = pptr->domain_argc; |
|
703 |
offv += sizeof (nssuint_t) * i; |
|
704 |
for (; --i >= 0; ) { |
|
705 |
*uptr++ = offc; |
|
706 |
len3 = strlen(*cv) + 1; |
|
707 |
(void) strlcpy(dptr, *cv++, len3); |
|
708 |
offc += len3; |
|
709 |
dptr += len3; |
|
710 |
} |
|
711 |
} |
|
712 |
if (pptr->groups_argc == 0) { |
|
713 |
pptr->groups_offv = (nssuint_t)0; |
|
714 |
} else { |
|
715 |
pptr->groups_offv = offv; |
|
716 |
cv = ing->groups.argv; |
|
717 |
i = pptr->groups_argc; |
|
718 |
offv += sizeof (nssuint_t) * i; |
|
719 |
for (; --i >= 0; ) { |
|
720 |
*uptr++ = offc; |
|
721 |
len3 = strlen(*cv) + 1; |
|
722 |
(void) strlcpy(dptr, *cv++, len3); |
|
723 |
offc += len3; |
|
724 |
dptr += len3; |
|
725 |
} |
|
726 |
} |
|
727 |
break; |
|
728 |
case 'T': |
|
729 |
sng = (struct nss_setnetgrent_args *)arg; |
|
730 |
if (sng->netgroup == NULL) |
|
731 |
return (NSS_NOTFOUND); |
|
732 |
len = strlen(sng->netgroup) + 1; |
|
733 |
if (len >= length) |
|
734 |
return (NSS_ERROR); |
|
735 |
(void) strlcpy(buffer, sng->netgroup, len); |
|
736 |
*rlen = len; |
|
737 |
break; |
|
738 |
default: |
|
739 |
return (NSS_ERROR); |
|
740 |
} |
|
741 |
} |
|
742 |
return (NSS_SUCCESS); |
|
743 |
} |
|
744 |
||
745 |
nss_status_t |
|
746 |
nss_default_key2str(void *buffer, size_t length, nss_XbyY_args_t *arg, |
|
747 |
const char *dbname, int dbop, size_t *rlen) |
|
748 |
{ |
|
749 |
int index; |
|
750 |
||
751 |
if (buffer == NULL || length == 0 || arg == NULL || |
|
752 |
dbname == NULL || rlen == NULL) |
|
753 |
return (NSS_ERROR); |
|
754 |
||
755 |
/* |
|
756 |
* If this is not one of the well known getXbyYs |
|
757 |
* (IE _printers special processing etc.) use a |
|
758 |
* local (non-nscd) getXbyY lookup. |
|
759 |
*/ |
|
760 |
if ((index = nss_dbop_search(dbname, (uint32_t)dbop)) < 0) |
|
761 |
return (NSS_TRYLOCAL); |
|
762 |
||
763 |
return (nss_pack_key2str(buffer, length, arg, dbname, |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
764 |
dbop, rlen, getXbyY_to_dbop[index].tostr)); |
2830 | 765 |
} |
766 |
||
767 |
/*ARGSUSED*/ |
|
768 |
void |
|
769 |
nss_packed_set_status(void *buffer, size_t length, nss_status_t status, |
|
770 |
nss_XbyY_args_t *arg) |
|
771 |
{ |
|
772 |
nss_pheader_t *pbuf = (nss_pheader_t *)buffer; |
|
773 |
nss_dbd_t *pdbd; |
|
774 |
char *dbn; |
|
775 |
||
776 |
/* sidestep odd cases */ |
|
777 |
pdbd = (nss_dbd_t *)((void *)((char *)buffer + pbuf->dbd_off)); |
|
778 |
dbn = (char *)pdbd + pdbd->o_name; |
|
779 |
if (pbuf->nss_dbop == NSS_DBOP_GROUP_BYMEMBER) { |
|
780 |
if (strcmp(dbn, NSS_DBNAM_GROUP) == 0) { |
|
781 |
struct nss_groupsbymem *in = |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
782 |
(struct nss_groupsbymem *)arg; |
2830 | 783 |
|
784 |
if (in->numgids >= 0) { |
|
785 |
pbuf->p_status = NSS_SUCCESS; |
|
786 |
pbuf->data_len = in->numgids * |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
787 |
sizeof (gid_t); |
2830 | 788 |
pbuf->p_herrno = 0; |
789 |
} else { |
|
790 |
pbuf->p_status = status; |
|
791 |
pbuf->p_errno = errno; |
|
792 |
pbuf->data_len = 0; |
|
793 |
pbuf->p_herrno = (uint32_t)arg->h_errno; |
|
794 |
} |
|
795 |
return; |
|
796 |
} |
|
797 |
} |
|
798 |
if (pbuf->nss_dbop == NSS_DBOP_NETGROUP_IN) { |
|
799 |
if (strcmp(dbn, NSS_DBNAM_NETGROUP) == 0) { |
|
800 |
struct nss_innetgr_args *in = |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
801 |
(struct nss_innetgr_args *)arg; |
2830 | 802 |
|
803 |
/* tell nss_unpack() operation is successful */ |
|
804 |
pbuf->data_len = 1; |
|
805 |
||
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
806 |
if (status != NSS_SUCCESS && status != NSS_NOTFOUND) { |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
807 |
pbuf->p_status = status; |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
808 |
pbuf->p_errno = errno; |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
809 |
return; |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
810 |
} |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
811 |
|
2830 | 812 |
if (in->status == NSS_NETGR_FOUND) { |
813 |
pbuf->p_status = NSS_SUCCESS; |
|
814 |
} else { |
|
815 |
pbuf->p_status = NSS_NOTFOUND; |
|
816 |
pbuf->p_errno = errno; |
|
817 |
} |
|
818 |
return; |
|
819 |
} |
|
820 |
} |
|
821 |
||
822 |
/* process normal cases */ |
|
823 |
if ((pbuf->p_status = status) != NSS_SUCCESS) { |
|
824 |
if (arg->erange == 1) |
|
825 |
pbuf->p_errno = ERANGE; |
|
826 |
else |
|
827 |
pbuf->p_errno = errno; |
|
828 |
} else |
|
829 |
pbuf->p_errno = 0; |
|
830 |
if (arg != NULL) { |
|
831 |
pbuf->p_herrno = (uint32_t)arg->h_errno; |
|
832 |
pbuf->data_len = (nssuint_t)arg->returnlen; |
|
833 |
} else { |
|
834 |
pbuf->p_herrno = 0; |
|
835 |
pbuf->data_len = 0; |
|
836 |
} |
|
837 |
} |
|
838 |
||
839 |
/* |
|
840 |
* nss_upack_key2arg |
|
841 |
* Private string to key unpacking function for getXbyY routines |
|
842 |
* This routine performs a scanf/printf like parse over the packed |
|
843 |
* string, to uppack and re-assemble the key in the args structure. |
|
844 |
* |
|
845 |
* buffer - Start of the key buffer location [in packed buffer] |
|
846 |
* length - Length of key buffer component |
|
847 |
* Key offsets are relative to start of key buffer location. |
|
848 |
* |
|
849 |
* Unpack fields Key |
|
850 |
* key.name n |
|
851 |
* key.number N |
|
852 |
* key.uid u |
|
853 |
* key.gid g |
|
854 |
* key.hostaddr h |
|
855 |
* key.ipnode i |
|
856 |
* key.projid p |
|
857 |
* key.serv(name) s |
|
858 |
* key.serv(port) S |
|
859 |
* key.ether e |
|
860 |
* key.pkey k |
|
861 |
* key.netaddr a |
|
862 |
* key.attrp A |
|
863 |
* groupsbymember I |
|
864 |
* innetgr_args t |
|
865 |
* setnetgr_args T |
|
866 |
* Assumes arguments are all valid |
|
867 |
*/ |
|
868 |
||
869 |
/*ARGSUSED*/ |
|
870 |
static nss_status_t |
|
871 |
nss_upack_key2arg(void *buffer, size_t length, char **dbname, |
|
872 |
int *dbop, nss_XbyY_args_t *arg, int index) |
|
873 |
{ |
|
874 |
nss_pheader_t *pbuf = (nss_pheader_t *)buffer; |
|
875 |
const char *strtype = NULL; |
|
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
876 |
nssuint_t off, *uptr, keysize; |
2830 | 877 |
size_t len, slop; |
878 |
int i, j; |
|
879 |
char **cv, *bptr; |
|
880 |
struct nss_setnetgrent_args *sng; |
|
881 |
struct nss_innetgr_args *ing; |
|
882 |
struct nss_groupsbymem *gbm; |
|
883 |
nss_pnetgr_t *pptr; |
|
884 |
_priv_execattr *pe; |
|
885 |
||
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
886 |
/* keysize is length of the key area */ |
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
887 |
keysize = pbuf->data_off - pbuf->key_off; |
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
888 |
|
2830 | 889 |
off = pbuf->key_off; |
890 |
bptr = (char *)buffer + off; |
|
891 |
uptr = (nssuint_t *)((void *)bptr); |
|
892 |
strtype = getXbyY_to_dbop[index].tostr; |
|
893 |
if (strtype == NULL) |
|
894 |
return (NSS_ERROR); |
|
895 |
while (*strtype) { |
|
896 |
switch (*strtype++) { |
|
897 |
case 'n': |
|
898 |
arg->key.name = (const char *)bptr; |
|
899 |
break; |
|
900 |
case 'N': |
|
901 |
arg->key.number = (int)(*uptr); |
|
902 |
break; |
|
903 |
case 'u': |
|
904 |
arg->key.uid = (uid_t)(*uptr); |
|
905 |
break; |
|
906 |
case 'g': |
|
907 |
arg->key.gid = (gid_t)(*uptr); |
|
908 |
break; |
|
909 |
case 'h': |
|
910 |
arg->key.hostaddr.len = (int)(*uptr++); |
|
911 |
arg->key.hostaddr.type = (int)(*uptr++); |
|
912 |
arg->key.hostaddr.addr = (const char *)uptr; |
|
913 |
break; |
|
914 |
case 'i': |
|
915 |
arg->key.ipnode.af_family = (int)(*uptr++); |
|
916 |
arg->key.ipnode.flags = (int)(*uptr++); |
|
917 |
arg->key.ipnode.name = (const char *)uptr; |
|
918 |
break; |
|
919 |
case 'p': |
|
920 |
arg->key.projid = (projid_t)(*uptr); |
|
921 |
break; |
|
922 |
case 's': |
|
923 |
arg->key.serv.serv.name = (const char *)bptr; |
|
924 |
len = strlen(arg->key.serv.serv.name) + 1; |
|
925 |
bptr += len; |
|
926 |
if (*(const char *)bptr == '\0') |
|
927 |
arg->key.serv.proto = NULL; |
|
928 |
else |
|
929 |
arg->key.serv.proto = (const char *)bptr; |
|
930 |
break; |
|
931 |
case 'S': |
|
932 |
arg->key.serv.serv.port = (int)(*uptr++); |
|
933 |
if (pbuf->key_len == sizeof (nssuint_t)) { |
|
934 |
arg->key.serv.proto = NULL; |
|
935 |
} else { |
|
936 |
bptr += sizeof (nssuint_t); |
|
937 |
arg->key.serv.proto = (const char *)bptr; |
|
938 |
} |
|
939 |
break; |
|
940 |
case 'e': |
|
941 |
arg->key.ether = bptr; |
|
942 |
break; |
|
943 |
case 'k': |
|
944 |
arg->key.pkey.name = (const char *)bptr; |
|
945 |
len = strlen(arg->key.pkey.name) + 1; |
|
946 |
bptr += len; |
|
947 |
arg->key.pkey.keytype = (const char *)bptr; |
|
948 |
break; |
|
949 |
case 'a': |
|
950 |
arg->key.netaddr.net = (uint32_t)(*uptr++); |
|
951 |
arg->key.netaddr.type = (int)(*uptr++); |
|
952 |
break; |
|
953 |
case 'A': |
|
954 |
pe = (_priv_execattr *)((void *)bptr); |
|
955 |
/* use slop space as priv_execattr structure */ |
|
956 |
arg->key.attrp = (void *)pe; |
|
957 |
/* skip over slop ... */ |
|
958 |
slop = sizeof (nssuint_t) * 16; |
|
959 |
uptr = (nssuint_t *)((void *)((char *)bptr + slop)); |
|
960 |
pe->search_flag = (int)*uptr++; |
|
961 |
bptr = (char *)uptr; |
|
962 |
if (*bptr == '\0') { |
|
963 |
pe->name = NULL; |
|
964 |
bptr++; |
|
965 |
} else { |
|
966 |
pe->name = (char *)bptr; |
|
967 |
bptr += strlen(pe->name) + 1; |
|
968 |
} |
|
969 |
if (*bptr == '\0') { |
|
970 |
pe->type = NULL; |
|
971 |
bptr++; |
|
972 |
} else { |
|
973 |
pe->type = (char *)bptr; |
|
974 |
bptr += strlen(pe->type) + 1; |
|
975 |
} |
|
976 |
if (*bptr == '\0') { |
|
977 |
pe->id = NULL; |
|
978 |
bptr++; |
|
979 |
} else { |
|
980 |
pe->id = (char *)bptr; |
|
981 |
bptr += strlen(pe->id) + 1; |
|
982 |
} |
|
983 |
if (*bptr == '\0') { |
|
984 |
pe->policy = NULL; |
|
985 |
} else { |
|
986 |
pe->policy = (char *)bptr; |
|
987 |
} |
|
988 |
pe->head_exec = NULL; |
|
989 |
pe->prev_exec = NULL; |
|
990 |
break; |
|
991 |
case 'I': |
|
992 |
gbm = (struct nss_groupsbymem *)arg; |
|
993 |
gbm->gid_array = (gid_t *) |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
994 |
((void *)((char *)pbuf + pbuf->data_off)); |
2830 | 995 |
gbm->force_slow_way = (int)(*uptr++); |
996 |
gbm->maxgids = (int)(*uptr++); |
|
997 |
gbm->numgids = (int)(*uptr++); |
|
998 |
if (gbm->numgids == 1) { |
|
999 |
/* insert initial group into data area */ |
|
3099
df972f671b58
6462185 /etc/hosts parsing is still retarded and broken
michen
parents:
2830
diff
changeset
|
1000 |
gbm->gid_array[0] = (gid_t)(*uptr++); |
df972f671b58
6462185 /etc/hosts parsing is still retarded and broken
michen
parents:
2830
diff
changeset
|
1001 |
} else |
df972f671b58
6462185 /etc/hosts parsing is still retarded and broken
michen
parents:
2830
diff
changeset
|
1002 |
uptr++; |
2830 | 1003 |
gbm->username = (const char *)uptr; |
1004 |
break; |
|
1005 |
case 't': |
|
1006 |
pptr = (nss_pnetgr_t *)((void *)bptr); |
|
1007 |
ing = (struct nss_innetgr_args *)arg; |
|
1008 |
ing->arg[NSS_NETGR_MACHINE].argc = pptr->machine_argc; |
|
1009 |
ing->arg[NSS_NETGR_USER].argc = pptr->user_argc; |
|
1010 |
ing->arg[NSS_NETGR_DOMAIN].argc = pptr->domain_argc; |
|
1011 |
ing->groups.argc = pptr->groups_argc; |
|
1012 |
||
1013 |
/* |
|
1014 |
* Start of argv pointer storage |
|
1015 |
*/ |
|
1016 |
off = ing->arg[NSS_NETGR_MACHINE].argc + |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1017 |
ing->arg[NSS_NETGR_USER].argc + |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1018 |
ing->arg[NSS_NETGR_DOMAIN].argc + |
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1019 |
ing->groups.argc; |
2830 | 1020 |
off *= sizeof (nssuint_t); |
1021 |
off += sizeof (nss_pnetgr_t); |
|
1022 |
||
1023 |
cv = (char **)((void *)(bptr + off)); |
|
1024 |
uptr = (nssuint_t *) |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1025 |
((void *)(bptr + sizeof (nss_pnetgr_t))); |
2830 | 1026 |
for (j = 0; j < NSS_NETGR_N; j++) { |
1027 |
ing->arg[j].argv = cv; |
|
1028 |
for (i = 0; i < ing->arg[j].argc; i++) { |
|
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1029 |
if (*uptr >= keysize) |
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1030 |
return (NSS_ERROR); |
2830 | 1031 |
*cv++ = (bptr + *uptr++); |
1032 |
} |
|
1033 |
} |
|
1034 |
ing->groups.argv = cv; |
|
1035 |
for (i = 0; i < ing->groups.argc; i++) { |
|
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1036 |
if (*uptr >= keysize) |
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1037 |
return (NSS_ERROR); |
2830 | 1038 |
*cv++ = (bptr + *uptr++); |
1039 |
} |
|
1040 |
break; |
|
1041 |
case 'T': |
|
1042 |
sng = (struct nss_setnetgrent_args *)arg; |
|
1043 |
sng->netgroup = (const char *)bptr; |
|
1044 |
sng->iterator = 0; |
|
1045 |
break; |
|
1046 |
||
1047 |
default: |
|
1048 |
return (NSS_ERROR); |
|
1049 |
} |
|
1050 |
} |
|
1051 |
return (NSS_SUCCESS); |
|
1052 |
} |
|
1053 |
||
1054 |
static nss_status_t |
|
1055 |
nss_pinit_funcs(int index, nss_db_initf_t *initf, nss_str2ent_t *s2e) |
|
1056 |
{ |
|
1057 |
const char *name; |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1058 |
void *htmp = NULL; |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1059 |
void *sym; |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1060 |
static void *handle = NULL; |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1061 |
static mutex_t handle_lock = DEFAULTMUTEX; |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1062 |
static mutex_t initf_lock = DEFAULTMUTEX; |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1063 |
static mutex_t s2e_lock = DEFAULTMUTEX; |
2830 | 1064 |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1065 |
if (handle == NULL) { |
5914
4cb75cba32df
6655337 calling dlopen() while holding a lock with lmutex_lock() can cause an ASSERT() failure in libc
raf
parents:
5477
diff
changeset
|
1066 |
htmp = dlopen((const char *)0, RTLD_LAZY); |
4cb75cba32df
6655337 calling dlopen() while holding a lock with lmutex_lock() can cause an ASSERT() failure in libc
raf
parents:
5477
diff
changeset
|
1067 |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1068 |
lmutex_lock(&handle_lock); |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1069 |
if (handle == NULL) { |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1070 |
if (htmp == NULL) { |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1071 |
lmutex_unlock(&handle_lock); |
2830 | 1072 |
return (NSS_ERROR); |
1073 |
} else { |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1074 |
membar_producer(); |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1075 |
handle = htmp; |
5914
4cb75cba32df
6655337 calling dlopen() while holding a lock with lmutex_lock() can cause an ASSERT() failure in libc
raf
parents:
5477
diff
changeset
|
1076 |
htmp = NULL; |
2830 | 1077 |
} |
1078 |
} |
|
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1079 |
lmutex_unlock(&handle_lock); |
5914
4cb75cba32df
6655337 calling dlopen() while holding a lock with lmutex_lock() can cause an ASSERT() failure in libc
raf
parents:
5477
diff
changeset
|
1080 |
if (htmp) |
11411
c2fe1bf96826
6894056 libc is not clean
Surya Prakki <Surya.Prakki@Sun.COM>
parents:
8765
diff
changeset
|
1081 |
(void) dlclose(htmp); |
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1082 |
} |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1083 |
membar_consumer(); |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1084 |
|
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1085 |
if (initf) { |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1086 |
if (getXbyY_to_dbop[index].initfnp == NULL) { |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1087 |
name = getXbyY_to_dbop[index].initfn; |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1088 |
if ((sym = dlsym(handle, name)) == NULL) |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1089 |
return (NSS_ERROR); |
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1090 |
lmutex_lock(&initf_lock); |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1091 |
if (getXbyY_to_dbop[index].initfnp == NULL) |
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1092 |
getXbyY_to_dbop[index].initfnp = sym; |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1093 |
membar_producer(); |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1094 |
lmutex_unlock(&initf_lock); |
2830 | 1095 |
} |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1096 |
membar_consumer(); |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1097 |
*initf = (nss_db_initf_t)getXbyY_to_dbop[index].initfnp; |
2830 | 1098 |
} |
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1099 |
if (s2e) { |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1100 |
if (getXbyY_to_dbop[index].strfnp == NULL) { |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1101 |
name = getXbyY_to_dbop[index].strfn; |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1102 |
if ((sym = dlsym(handle, name)) == NULL) |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1103 |
return (NSS_ERROR); |
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1104 |
lmutex_lock(&s2e_lock); |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1105 |
if (getXbyY_to_dbop[index].strfnp == NULL) |
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1106 |
getXbyY_to_dbop[index].strfnp = sym; |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1107 |
membar_producer(); |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1108 |
lmutex_unlock(&s2e_lock); |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1109 |
} |
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1110 |
membar_consumer(); |
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
5914
diff
changeset
|
1111 |
*s2e = (nss_str2ent_t)getXbyY_to_dbop[index].strfnp; |
4046
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1112 |
} |
18a99a0d9b30
6496124 nscd: Unable to login with pam_unix_auth error
michen
parents:
3864
diff
changeset
|
1113 |
|
2830 | 1114 |
return (NSS_SUCCESS); |
1115 |
} |
|
1116 |
||
1117 |
nss_status_t |
|
1118 |
nss_packed_getkey(void *buffer, size_t length, char **dbname, |
|
1119 |
int *dbop, nss_XbyY_args_t *arg) |
|
1120 |
{ |
|
1121 |
nss_pheader_t *pbuf = (nss_pheader_t *)buffer; |
|
1122 |
nss_dbd_t *pdbd; |
|
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1123 |
nssuint_t off, dbdsize; |
2830 | 1124 |
int index; |
1125 |
||
1126 |
if (buffer == NULL || length == 0 || dbop == NULL || |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1127 |
arg == NULL || dbname == NULL) |
2830 | 1128 |
return (NSS_ERROR); |
1129 |
||
1130 |
*dbop = pbuf->nss_dbop; |
|
1131 |
off = pbuf->dbd_off; |
|
1132 |
pdbd = (nss_dbd_t *)((void *)((char *)buffer + off)); |
|
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1133 |
dbdsize = pbuf->key_off - pbuf->dbd_off; |
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1134 |
if (pdbd->o_name >= dbdsize || pdbd->o_config_name >= dbdsize || |
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1135 |
pdbd->o_default_config >= dbdsize) |
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1136 |
return (NSS_ERROR); |
2830 | 1137 |
*dbname = (char *)buffer + off + pdbd->o_name; |
1138 |
if ((index = nss_dbop_search(*dbname, (uint32_t)*dbop)) < 0) |
|
1139 |
return (NSS_ERROR); |
|
1140 |
return (nss_upack_key2arg(buffer, length, dbname, dbop, arg, index)); |
|
1141 |
} |
|
1142 |
||
1143 |
||
1144 |
/* |
|
1145 |
* str2packent: Standard format interposed str2X function for normal APIs |
|
1146 |
* |
|
1147 |
* Return values: 0 = success, 1 = parse error, 2 = erange ... |
|
1148 |
* |
|
1149 |
* The structure pointer is ignored since this is a nscd side packed request. |
|
1150 |
* The client side routine does all the real parsing; we just check limits and |
|
1151 |
* store the entry in the buffer we were passed by the caller. |
|
1152 |
*/ |
|
1153 |
||
1154 |
/*ARGSUSED*/ |
|
1155 |
static int |
|
1156 |
str2packent( |
|
1157 |
const char *instr, |
|
1158 |
int lenstr, |
|
1159 |
void *ent, /* really (char *) */ |
|
1160 |
char *buffer, |
|
1161 |
int buflen |
|
1162 |
) |
|
1163 |
{ |
|
1164 |
if (buflen <= lenstr) { /* not enough buffer */ |
|
1165 |
return (NSS_STR_PARSE_ERANGE); |
|
1166 |
} |
|
1167 |
(void) memmove(buffer, instr, lenstr); |
|
1168 |
buffer[lenstr] = '\0'; |
|
1169 |
||
1170 |
return (NSS_STR_PARSE_SUCCESS); |
|
1171 |
} |
|
1172 |
||
1173 |
/* |
|
1174 |
* Initialize db_root, initf, dbop and arg from a packed buffer |
|
1175 |
*/ |
|
1176 |
||
1177 |
/*ARGSUSED*/ |
|
1178 |
nss_status_t |
|
1179 |
nss_packed_arg_init(void *buffer, size_t length, nss_db_root_t *db_root, |
|
1180 |
nss_db_initf_t *initf, int *dbop, nss_XbyY_args_t *arg) |
|
1181 |
{ |
|
1182 |
nss_pheader_t *pbuf = (nss_pheader_t *)buffer; |
|
1183 |
nss_str2ent_t s2e = str2packent; |
|
1184 |
nss_str2ent_t real_s2e = NULL; |
|
1185 |
nss_dbd_t *pdbd; |
|
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1186 |
nssuint_t off, dbdsize; |
2830 | 1187 |
char *dbname, *bptr; |
1188 |
size_t len; |
|
1189 |
int index; |
|
1190 |
||
1191 |
if (buffer == NULL || length == 0 || |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1192 |
dbop == NULL || arg == NULL) |
2830 | 1193 |
return (NSS_ERROR); |
1194 |
||
1195 |
/* init dbop */ |
|
1196 |
*dbop = pbuf->nss_dbop; |
|
1197 |
off = pbuf->dbd_off; |
|
1198 |
pdbd = (nss_dbd_t *)((void *)((char *)buffer + off)); |
|
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1199 |
dbdsize = pbuf->key_off - pbuf->dbd_off; |
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1200 |
if (pdbd->o_name >= dbdsize || pdbd->o_config_name >= dbdsize || |
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1201 |
pdbd->o_default_config >= dbdsize) |
4142
0d7fa83a8b00
6548196 Multiple memory corruption vulnerabilities in nscd(1M)
michen
parents:
4046
diff
changeset
|
1202 |
return (NSS_ERROR); |
2830 | 1203 |
dbname = (char *)buffer + off + pdbd->o_name; |
1204 |
if ((index = nss_dbop_search(dbname, (uint32_t)*dbop)) < 0) |
|
1205 |
return (NSS_ERROR); |
|
1206 |
||
1207 |
/* db_root is initialized by nscd's based on door info */ |
|
1208 |
/* do nothing here */ |
|
1209 |
||
1210 |
/* init key information - (and get dbname dbop etc...) */ |
|
1211 |
if (nss_upack_key2arg(buffer, length, &dbname, |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1212 |
dbop, arg, index) != NSS_SUCCESS) |
2830 | 1213 |
return (NSS_ERROR); |
1214 |
||
1215 |
/* possible audituser init */ |
|
1216 |
if (strcmp(dbname, NSS_DBNAM_AUTHATTR) == 0) |
|
1217 |
arg->h_errno = (int)pbuf->p_herrno; |
|
1218 |
||
1219 |
bptr = (char *)buffer + pbuf->data_off; |
|
1220 |
len = (size_t)pbuf->data_len; |
|
1221 |
||
1222 |
/* sidestep odd arg cases */ |
|
1223 |
if (*dbop == NSS_DBOP_GROUP_BYMEMBER && |
|
1224 |
strcmp(dbname, NSS_DBNAM_GROUP) == 0) { |
|
1225 |
/* get initf and str2ent functions */ |
|
1226 |
if (nss_pinit_funcs(index, initf, &real_s2e) != NSS_SUCCESS) |
|
1227 |
return (NSS_ERROR); |
|
1228 |
((struct nss_groupsbymem *)arg)->str2ent = real_s2e; |
|
3099
df972f671b58
6462185 /etc/hosts parsing is still retarded and broken
michen
parents:
2830
diff
changeset
|
1229 |
((struct nss_groupsbymem *)arg)->process_cstr = process_cstr; |
2830 | 1230 |
return (NSS_SUCCESS); |
1231 |
} |
|
1232 |
if (pbuf->nss_dbop == NSS_DBOP_NETGROUP_IN && |
|
5477
0cf09bc2aa41
6602070 netgroup lookup should return NSS_UNAVAIL if only files backend is used
andra
parents:
4142
diff
changeset
|
1233 |
strcmp(dbname, NSS_DBNAM_NETGROUP) == 0) { |
2830 | 1234 |
return (NSS_SUCCESS); |
1235 |
} |
|
1236 |
||
1237 |
/* get initf and str2ent functions */ |
|
1238 |
if (nss_pinit_funcs(index, initf, NULL) != NSS_SUCCESS) |
|
1239 |
return (NSS_ERROR); |
|
1240 |
||
1241 |
/* init normal arg cases */ |
|
1242 |
NSS_XbyY_INIT(arg, NULL, bptr, len, s2e); |
|
1243 |
arg->h_errno = 0; |
|
1244 |
||
1245 |
return (NSS_SUCCESS); |
|
1246 |
} |
|
1247 |
||
1248 |
/* |
|
1249 |
* Initialize db_root, initf, dbop, contextp and arg from a packed buffer |
|
1250 |
*/ |
|
1251 |
||
1252 |
/*ARGSUSED*/ |
|
1253 |
nss_status_t |
|
1254 |
nss_packed_context_init(void *buffer, size_t length, nss_db_root_t *db_root, |
|
1255 |
nss_db_initf_t *initf, nss_getent_t **contextp, |
|
1256 |
nss_XbyY_args_t *arg) |
|
1257 |
{ |
|
1258 |
nss_pheader_t *pbuf = (nss_pheader_t *)buffer; |
|
1259 |
nss_str2ent_t s2e = str2packent; |
|
1260 |
char *bptr; |
|
1261 |
size_t len; |
|
1262 |
||
1263 |
/* init arg */ |
|
1264 |
if (arg != NULL) { |
|
1265 |
bptr = (char *)buffer + pbuf->data_off; |
|
1266 |
len = (size_t)pbuf->data_len; |
|
1267 |
NSS_XbyY_INIT(arg, NULL, bptr, len, s2e); |
|
1268 |
} |
|
1269 |
||
1270 |
return (NSS_SUCCESS); |
|
1271 |
} |