Print this page
5910 libnisdb won't build with modern GCC
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libnisdb/ldap_ruleval.c
+++ new/usr/src/lib/libnisdb/ldap_ruleval.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 + * Copyright 2015 Gary Mills
22 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 24 * Use is subject to license terms.
24 25 */
25 26
26 27
27 28 #include <lber.h>
28 29 #include <ldap.h>
29 30 #include <strings.h>
30 31
31 32 #include "nisdb_mt.h"
32 33
33 34 #include "ldap_util.h"
34 35 #include "ldap_val.h"
35 36 #include "ldap_attr.h"
36 37 #include "ldap_ldap.h"
37 38 #include "ldap_ruleval.h"
38 39
39 40
40 41 /*
41 42 * Free an array of 'count' rule-value elements.
42 43 */
43 44 void
44 45 freeRuleValue(__nis_rule_value_t *rv, int count) {
45 46 int n, i, j;
46 47
47 48 if (rv == 0)
48 49 return;
49 50
50 51 for (n = 0; n < count; n++) {
51 52
52 53 if (rv[n].colName != 0) {
53 54 for (i = 0; i < rv[n].numColumns; i++) {
54 55 sfree(rv[n].colName[i]);
55 56 }
56 57 free(rv[n].colName);
57 58 }
58 59 if (rv[n].colVal != 0) {
59 60 for (i = 0; i < rv[n].numColumns; i++) {
60 61 for (j = 0; j < rv[n].colVal[i].numVals; j++) {
61 62 sfree(rv[n].colVal[i].val[j].value);
62 63 }
63 64 if (rv[n].colVal[i].numVals > 0)
64 65 sfree(rv[n].colVal[i].val);
65 66 }
66 67 free(rv[n].colVal);
67 68 }
68 69
69 70 if (rv[n].attrName != 0) {
70 71 for (i = 0; i < rv[n].numAttrs; i++) {
71 72 sfree(rv[n].attrName[i]);
72 73 }
73 74 free(rv[n].attrName);
74 75 }
75 76 if (rv[n].attrVal != 0) {
76 77 for (i = 0; i < rv[n].numAttrs; i++) {
77 78 for (j = 0; j < rv[n].attrVal[i].numVals;
78 79 j++) {
79 80 sfree(rv[n].attrVal[i].val[j].value);
80 81 }
81 82 if (rv[n].attrVal[i].numVals > 0)
82 83 sfree(rv[n].attrVal[i].val);
83 84 }
84 85 free(rv[n].attrVal);
85 86 }
86 87
87 88 }
88 89 sfree(rv);
89 90 }
90 91
91 92 /*
92 93 * Return an array of 'count' __nis_rule_value_t elements, initialized
93 94 * to be copies of 'rvIn' if supplied; empty otherwise.
94 95 */
95 96 __nis_rule_value_t *
96 97 initRuleValue(int count, __nis_rule_value_t *rvIn) {
97 98 return (growRuleValue(0, count, 0, rvIn));
98 99 }
99 100
100 101 static const __nis_rule_value_t rvZero = {0};
101 102
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
102 103 /*
103 104 * Grow 'old' from 'oldCount' to 'newCount' elements, initialize the
104 105 * new portion to 'rvIn' (empty if not supplied), and return a pointer
105 106 * to the result. Following a call to this function, the caller must
106 107 * refer only to the returned array, not to 'old'.
107 108 */
108 109 __nis_rule_value_t *
109 110 growRuleValue(int oldCount, int newCount, __nis_rule_value_t *old,
110 111 __nis_rule_value_t *rvIn) {
111 112 __nis_rule_value_t *rv;
112 - int i, j;
113 + int i;
113 114 char *myself = "growRuleValue";
114 115
115 116 if (newCount <= 0 || newCount <= oldCount)
116 117 return (old);
117 118
118 119 if (oldCount <= 0) {
119 120 oldCount = 0;
120 121 old = 0;
121 122 }
122 123
123 124 if (rvIn == 0)
124 125 rvIn = (__nis_rule_value_t *)&rvZero;
125 126
126 127 rv = realloc(old, newCount * sizeof (rv[0]));
127 128 if (rv == 0) {
128 129 logmsg(MSG_NOMEM, LOG_ERR,
129 130 "%s: realloc(%d ((%d+%d)*%d)) => 0",
130 131 myself, (oldCount+newCount) * sizeof (rv[0]),
131 132 oldCount, newCount, sizeof (rv[0]));
132 133 freeRuleValue(old, oldCount);
133 134 return (0);
134 135 }
135 136
136 137 (void) memset(&rv[oldCount], 0, (newCount-oldCount)*sizeof (rv[0]));
137 138
138 139 for (i = oldCount; i < newCount; i++) {
139 140 rv[i].numColumns = rvIn->numColumns;
140 141 if (rv[i].numColumns > 0) {
141 142 rv[i].colName = cloneName(rvIn->colName,
142 143 rv[i].numColumns);
143 144 rv[i].colVal = cloneValue(rvIn->colVal,
144 145 rv[i].numColumns);
145 146 }
146 147 if (rv[i].numColumns > 0 &&
147 148 (rv[i].colName == 0 || rv[i].colVal == 0)) {
148 149 freeRuleValue(rv, i);
149 150 return (0);
150 151 }
151 152 rv[i].numAttrs = rvIn->numAttrs;
152 153 rv[i].attrName = cloneName(rvIn->attrName, rv[i].numAttrs);
153 154 rv[i].attrVal = cloneValue(rvIn->attrVal, rv[i].numAttrs);
154 155 if (rv[i].numAttrs > 0 &&
155 156 (rv[i].attrName == 0 || rv[i].attrVal == 0)) {
156 157 freeRuleValue(rv, i);
157 158 return (0);
158 159 }
159 160 }
160 161
161 162 return (rv);
162 163 }
163 164
164 165 /*
165 166 * Merge the source rule-value 's' into the target rule-value 't'.
166 167 * If successful, unless 's' is a sub-set of 't', 't' will be changed
167 168 * on exit, and will contain the values from 's' as well.
168 169 */
169 170 int
170 171 mergeRuleValue(__nis_rule_value_t *t, __nis_rule_value_t *s) {
171 172 int i, j;
172 173
173 174 if (s == 0)
174 175 return (0);
175 176 else if (t == 0)
176 177 return (-1);
177 178
178 179 for (i = 0; i < s->numColumns; i++) {
179 180 for (j = 0; j < s->colVal[i].numVals; j++) {
180 181 if (addCol2RuleValue(s->colVal[i].type, s->colName[i],
181 182 s->colVal[i].val[j].value,
182 183 s->colVal[i].val[j].length,
183 184 t))
184 185 return (-1);
185 186 }
186 187 }
187 188
188 189 for (i = 0; i < s->numAttrs; i++) {
189 190 for (j = 0; j < s->attrVal[i].numVals; j++) {
190 191 if (addAttr2RuleValue(s->attrVal[i].type,
191 192 s->attrName[i],
192 193 s->attrVal[i].val[j].value,
193 194 s->attrVal[i].val[j].length,
194 195 t))
195 196 return (-1);
196 197 }
197 198 }
198 199
199 200 return (0);
200 201 }
201 202
202 203 static int
203 204 addVal2RuleValue(char *msg, int caseSens, int snipNul, __nis_value_type_t type,
204 205 char *name, void *value, int valueLen,
205 206 int *numP, char ***inNameP, __nis_value_t **inValP) {
206 207 int i, j, copyLen = valueLen;
207 208 __nis_single_value_t *v;
208 209 char **inName = *inNameP;
209 210 __nis_value_t *inVal = *inValP;
210 211 int num = *numP;
211 212 int (*comp)(const char *s1, const char *s2);
212 213 char *myself = "addVal2RuleValue";
213 214
214 215 /* Internal function, so assume arguments OK */
215 216
216 217 if (msg == 0)
217 218 msg = myself;
218 219
219 220 /* Should we match the 'inName' value case sensitive or not ? */
220 221 if (caseSens)
221 222 comp = strcmp;
222 223 else
223 224 comp = strcasecmp;
224 225
225 226 /*
226 227 * String-valued NIS+ entries count the concluding NUL in the
227 228 * length, while LDAP entries don't. In order to support this,
228 229 * we implement the following for vt_string value types:
229 230 *
230 231 * If the last byte of the value isn't a NUL, add one to the
231 232 * allocated length, so that there always is a NUL after the
232 233 * value, making it safe to pass to strcmp() etc.
233 234 *
234 235 * If 'snipNul' is set (presumably meaning we're inserting a
235 236 * value derived from a NIS+ entry), and the last byte of the
236 237 * value already is a NUL, decrement the length to be copied by
237 238 * one. This (a) doesn't count the NUL in the value length, but
238 239 * (b) still leaves a NUL following the value.
239 240 *
240 241 * In N2L, for all cases we set 'copyLen' to the number of non-0
241 242 * characters in 'value'.
242 243 */
243 244 if (type == vt_string && valueLen > 0) {
244 245 char *charval = value;
245 246
246 247 if (charval[valueLen-1] != '\0')
247 248 valueLen += 1;
248 249 else if (yp2ldap || snipNul)
249 250 copyLen -= 1;
250 251 } else if (valueLen == 0) {
251 252 /*
252 253 * If the 'value' pointer is non-NULL, we create a zero-
253 254 * length value with one byte allocated. This takes care
254 255 * of empty strings.
255 256 */
256 257 valueLen += 1;
257 258 }
258 259
259 260 /* If we already have values for this attribute, add another one */
260 261 for (i = 0; i < num; i++) {
261 262 if ((*comp)(inName[i], name) == 0) {
262 263
263 264 /*
264 265 * Our caller often doesn't know the type of the
265 266 * value; this happens because the type (vt_string
266 267 * or vt_ber) is determined by the format in the
267 268 * rule sets, and we may be invoked as a preparation
268 269 * for evaluating the rules. Hence, we only use the
269 270 * supplied 'type' if we need to create a value.
270 271 * Otherwise, we accept mixed types.
271 272 *
272 273 * Strings are OK in any case, since we always make
273 274 * sure to have a zero byte at the end of any value,
274 275 * whatever the type.
275 276 */
276 277
277 278 if (inVal[i].numVals < 0) {
278 279 /*
279 280 * Used to indicate deletion of attribute,
280 281 * so we honor that and don't add a value.
281 282 */
282 283 return (0);
283 284 }
284 285
285 286 /*
286 287 * If 'value' is NULL, we should delete, so
287 288 * remove any existing values, and set the
288 289 * 'numVals' field to -1.
289 290 */
290 291 if (value == 0) {
291 292 for (j = 0; j < inVal[i].numVals; j++) {
292 293 sfree(inVal[i].val[j].value);
293 294 }
294 295 sfree(inVal[i].val);
295 296 inVal[i].val = 0;
296 297 inVal[i].numVals = -1;
297 298 return (0);
298 299 }
299 300
300 301 /* Is the value a duplicate ? */
301 302 for (j = 0; j < inVal[i].numVals; j++) {
302 303 if (copyLen == inVal[i].val[j].length &&
303 304 memcmp(value, inVal[i].val[j].value,
304 305 copyLen) == 0) {
305 306 break;
306 307 }
307 308 }
308 309 if (j < inVal[i].numVals)
309 310 return (0);
310 311
311 312 /* Not a duplicate, so add the name/value pair */
312 313 v = realloc(inVal[i].val,
313 314 (inVal[i].numVals+1) *
314 315 sizeof (inVal[i].val[0]));
315 316 if (v == 0)
316 317 return (-1);
317 318 inVal[i].val = v;
318 319 v[inVal[i].numVals].length = copyLen;
319 320 v[inVal[i].numVals].value = am(msg, valueLen);
320 321 if (v[inVal[i].numVals].value == 0 &&
321 322 value != 0) {
322 323 sfree(v);
323 324 return (-1);
324 325 }
325 326 memcpy(v[inVal[i].numVals].value, value, copyLen);
326 327 inVal[i].numVals++;
327 328
328 329 return (0);
329 330 }
330 331 }
331 332
332 333 /* No previous value for this attribute */
333 334
334 335 /*
335 336 * value == 0 means deletion, in which case we create a
336 337 * __nis_value_t with the numVals field set to -1.
337 338 */
338 339 if (value != 0) {
339 340 if ((v = am(msg, sizeof (*v))) == 0)
340 341 return (-1);
341 342 v->length = copyLen;
342 343 v->value = am(msg, valueLen);
343 344 if (v->value == 0 && value != 0) {
344 345 sfree(v);
345 346 return (-1);
346 347 }
347 348 memcpy(v->value, value, copyLen);
348 349 }
349 350
350 351 inVal = realloc(inVal, (num+1)*sizeof (inVal[0]));
351 352 if (inVal == 0) {
352 353 if (value != 0) {
353 354 sfree(v->value);
354 355 sfree(v);
355 356 }
356 357 return (-1);
357 358 }
358 359 *inValP = inVal;
359 360
360 361 inName = realloc(inName,
361 362 (num+1)*sizeof (inName[0]));
362 363 if (inName == 0 || (inName[num] =
363 364 sdup(msg, T, name)) == 0) {
364 365 sfree(v->value);
365 366 sfree(v);
366 367 return (-1);
367 368 }
368 369 *inNameP = inName;
369 370
370 371 inVal[num].type = type;
371 372 inVal[num].repeat = 0;
372 373 if (value != 0) {
373 374 inVal[num].numVals = 1;
374 375 inVal[num].val = v;
375 376 } else {
376 377 inVal[num].numVals = -1;
377 378 inVal[num].val = 0;
378 379 }
379 380
380 381 *numP += 1;
381 382
382 383 return (0);
383 384 }
384 385
385 386 int
386 387 addAttr2RuleValue(__nis_value_type_t type, char *name, void *value,
387 388 int valueLen, __nis_rule_value_t *rv) {
388 389 char *myself = "addAttr2RuleValue";
389 390
390 391 if (name == 0 || rv == 0)
391 392 return (-1);
392 393
393 394 return (addVal2RuleValue(myself, 0, 0, type, name, value, valueLen,
394 395 &rv->numAttrs, &rv->attrName, &rv->attrVal));
395 396 }
396 397
397 398 int
398 399 addSAttr2RuleValue(char *name, char *value, __nis_rule_value_t *rv) {
399 400 return (addAttr2RuleValue(vt_string, name, value, slen(value), rv));
400 401 }
401 402
402 403 int
403 404 addCol2RuleValue(__nis_value_type_t type, char *name, void *value,
404 405 int valueLen, __nis_rule_value_t *rv) {
405 406 char *myself = "addCol2RuleValue";
406 407
407 408 if (name == 0 || rv == 0)
408 409 return (-1);
409 410
410 411 return (addVal2RuleValue(myself, 1, 1, type, name, value, valueLen,
411 412 &rv->numColumns, &rv->colName, &rv->colVal));
412 413 }
413 414
414 415 int
415 416 addSCol2RuleValue(char *name, char *value, __nis_rule_value_t *rv) {
416 417 return (addCol2RuleValue(vt_string, name, value, slen(value), rv));
417 418 }
↓ open down ↓ |
295 lines elided |
↑ open up ↑ |
418 419
419 420 /*
420 421 * Given a table mapping, a NIS+ DB query, and (optionally) an existing
421 422 * and compatible __nis_rule_value_t, return a new __nis_rule_value_t
422 423 * with the values from the query added.
423 424 */
424 425 __nis_rule_value_t *
425 426 buildNisPlusRuleValue(__nis_table_mapping_t *t, db_query *q,
426 427 __nis_rule_value_t *rv) {
427 428 int i;
428 - __nis_single_value_t *sv;
429 - char *myself = "buildNisPlusRuleValue";
430 429
431 430 if (t == 0 || q == 0)
432 431 return (0);
433 432
434 433 rv = initRuleValue(1, rv);
435 434 if (rv == 0)
436 435 return (0);
437 436
438 437 for (i = 0; i < q->components.components_len; i++) {
439 - int ic;
440 - int iv, v, dup;
441 - int len;
442 438
443 439 /* Ignore out-of-range column index */
444 440 if (q->components.components_val[i].which_index >=
445 441 t->numColumns)
446 442 continue;
447 443
448 444 /*
449 445 * Add the query value. A NULL value indicates deletion,
450 446 * but addCol2RuleValue() takes care of that for us.
451 447 */
452 448 if (addCol2RuleValue(vt_string,
453 449 t->column[q->components.components_val[i].
454 450 which_index],
455 451 q->components.components_val[i].index_value->
456 452 itemvalue.itemvalue_val,
457 453 q->components.components_val[i].index_value->
458 454 itemvalue.itemvalue_len, rv) != 0) {
459 455 freeRuleValue(rv, 1);
460 456 rv = 0;
461 457 break;
462 458 }
463 459 }
464 460
465 461 return (rv);
466 462 }
467 463
468 464
469 465 /*
470 466 * Given a LHS rule 'rl', return an array containing the item names,
471 467 * and the number of elements in the array in '*numItems'.
472 468 *
473 469 * If there are 'me_match' __nis_mapping_element_t's, we use the
474 470 * supplied '*rval' (if any) to derive values for the items in
475 471 * the 'me_match', and add the values thus derived to '*rval' (in
476 472 * which case the '*rval' pointer will change; the old '*rval'
477 473 * is deleted).
478 474 */
479 475 __nis_mapping_item_t *
480 476 buildLvalue(__nis_mapping_rlhs_t *rl, __nis_value_t **rval, int *numItems) {
481 477 __nis_value_t *val, *r;
482 478 __nis_mapping_item_t *item = 0;
483 479 int i, n, ni = 0, nv = 0;
484 480 int repeat = 0;
485 481
486 482 if (rl == 0)
487 483 return (0);
488 484
489 485 if (rval != 0) {
490 486 r = *rval;
491 487 repeat = r->repeat;
492 488 } else
493 489 r = 0;
494 490
495 491 /* If there is more than one element, we concatenate the items */
496 492 for (i = 0; i < rl->numElements; i++) {
497 493 __nis_mapping_element_t *e = &rl->element[i];
498 494 __nis_mapping_item_t *olditem, *tmpitem = 0;
499 495 __nis_value_t **tmp;
500 496
501 497 switch (e->type) {
502 498 case me_item:
503 499 tmpitem = cloneItem(&e->element.item);
504 500 break;
505 501 case me_match:
506 502 /*
507 503 * Obtain values for the items in the 'me_match'
508 504 * element.
509 505 */
510 506 tmp = matchMappingItem(e->element.match.fmt, r, &nv,
511 507 0, 0);
512 508 if (tmp != 0) {
513 509 freeValue(r, 1);
514 510 val = 0;
515 511 for (n = 0; n < nv; n++) {
516 512 r = concatenateValues(val, tmp[n]);
517 513 freeValue(val, 1);
518 514 freeValue(tmp[n], 1);
519 515 val = r;
520 516 if (val == 0) {
521 517 for (n++; n < nv; n++) {
522 518 freeValue(tmp[n], 1);
523 519 }
524 520 break;
525 521 }
526 522 }
527 523 free(tmp);
528 524 if (rval != 0) {
529 525 if (repeat && val != 0)
530 526 val->repeat = repeat;
531 527 *rval = val;
532 528 }
533 529 for (n = 0; n < e->element.match.numItems;
534 530 n++) {
535 531 olditem = item;
536 532 item = concatenateMappingItem(item, ni,
537 533 &e->element.match.item[n]);
538 534 freeMappingItem(olditem, ni);
539 535 if (item == 0) {
540 536 ni = 0;
541 537 break;
542 538 }
543 539 ni++;
544 540 }
545 541 }
546 542 break;
547 543 case me_print:
548 544 case me_split:
549 545 case me_extract:
550 546 default:
551 547 /* These shouldn't show up on the LHS; ignore */
552 548 break;
553 549 }
554 550
555 551 if (tmpitem != 0) {
556 552 olditem = item;
557 553 item = concatenateMappingItem(item, ni, tmpitem);
558 554 freeMappingItem(olditem, ni);
559 555 freeMappingItem(tmpitem, 1);
560 556 ni++;
561 557 if (item == 0) {
562 558 ni = 0;
563 559 break;
564 560 }
565 561 }
566 562 }
567 563
568 564 if (numItems != 0)
569 565 *numItems = ni;
570 566
571 567 return (item);
572 568 }
573 569
574 570 __nis_value_t *
575 571 buildRvalue(__nis_mapping_rlhs_t *rl, __nis_mapping_item_type_t native,
576 572 __nis_rule_value_t *rv, int *stat) {
577 573 __nis_value_t *val, *vold = 0, *vnew;
578 574 int i;
579 575 char *myself = "buildRvalue";
580 576
581 577 if (rl == 0 || rl->numElements <= 0) {
582 578 /*
583 579 * No RHS indicates deletion, as does a __nis_value_t
584 580 * with numVals == -1, so we return such a creature.
585 581 */
586 582 val = am(myself, sizeof (*val));
587 583 if (val != 0) {
588 584 val->type = vt_string;
589 585 val->numVals = -1;
590 586 }
591 587 return (val);
592 588 }
593 589
594 590 /* If there is more than one element, we concatenate the values */
595 591 for (i = 0; i < rl->numElements; i++) {
596 592 vnew = getMappingElement(&rl->element[i], native, rv, stat);
597 593 val = concatenateValues(vold, vnew);
598 594 freeValue(vnew, 1);
599 595 freeValue(vold, 1);
600 596 vold = val;
601 597 }
602 598 return (val);
603 599 }
604 600
605 601 /*
606 602 * Derive values for the LDAP attributes specified by the rule 'r',
607 603 * and add them to the rule-value 'rv'.
608 604 *
609 605 * If 'doAssign' is set, out-of-context assignments are performed,
↓ open down ↓ |
158 lines elided |
↑ open up ↑ |
610 606 * otherwise not.
611 607 */
612 608 __nis_rule_value_t *
613 609 addLdapRuleValue(__nis_table_mapping_t *t,
614 610 __nis_mapping_rule_t *r,
615 611 __nis_mapping_item_type_t lnative,
616 612 __nis_mapping_item_type_t rnative,
617 613 __nis_rule_value_t *rv,
618 614 int doAssign, int *stat) {
619 615 int i, j;
620 - char **new;
621 616 __nis_value_t *rval, *lval;
622 - __nis_buffer_t b = {0, 0};
623 617 __nis_mapping_item_t *litem;
624 618 int numItems;
625 619 char **dn = 0;
626 620 int numDN = 0;
627 621 char *myself = "addLdapRuleValue";
628 622
629 623
630 624 /* Do we have the required values ? */
631 625 if (rv == 0)
632 626 return (0);
633 627
634 628 /*
635 629 * Establish appropriate search base. For rnative == mit_nisplus,
636 630 * we're deriving LDAP attribute values from NIS+ columns; in other
637 631 * words, we're writing to LDAP, and should use the write.base value.
638 632 */
639 633 __nisdb_get_tsd()->searchBase = (rnative == mit_nisplus) ?
640 634 t->objectDN->write.base : t->objectDN->read.base;
641 635
642 636 /* Set escapeFlag if LHS is "dn" to escape special chars */
643 637 if (yp2ldap && r->lhs.numElements == 1 &&
644 638 r->lhs.element->type == me_item &&
645 639 r->lhs.element->element.item.type == mit_ldap &&
646 640 strcasecmp(r->lhs.element->element.item.name, "dn") == 0) {
647 641 __nisdb_get_tsd()->escapeFlag = '1';
648 642 }
649 643
650 644 /* Build the RHS value */
651 645 rval = buildRvalue(&r->rhs, rnative, rv, stat);
652 646
653 647 /* Reset escapeFlag */
654 648 __nisdb_get_tsd()->escapeFlag = '\0';
655 649
656 650 if (rval == 0)
657 651 return (rv);
658 652
659 653 /*
660 654 * Special case: If we got no value for the RHS (presumably because
661 655 * we're missing one or more item values), we don't produce an lval.
662 656 * Note that this isn't the same thing as an empty value, which we
663 657 * faithfully try to transmit to LDAP.
664 658 */
665 659 if (rval->numVals == 1 && rval->val[0].value == 0) {
666 660 freeValue(rval, 1);
667 661 return (rv);
668 662 }
669 663
670 664 /* Obtain the LHS item names */
671 665 litem = buildLvalue(&r->lhs, &rval, &numItems);
672 666 if (litem == 0) {
673 667 freeValue(rval, 1);
674 668 return (rv);
675 669 }
676 670
677 671 /* Get string representations of the LHS item names */
678 672 lval = 0;
679 673 for (i = 0; i < numItems; i++) {
680 674 __nis_value_t *tmpval, *old;
681 675
682 676 tmpval = getMappingItem(&litem[i], lnative, 0, 0, NULL);
683 677
684 678 /*
685 679 * If the LHS item is out-of-context, we do the
686 680 * assignment right here.
687 681 */
688 682 if (doAssign && litem[i].type == mit_ldap &&
689 683 litem[i].searchSpec.triple.scope !=
690 684 LDAP_SCOPE_UNKNOWN &&
691 685 slen(litem[i].searchSpec.triple.base) > 0 &&
692 686 (slen(litem[i].searchSpec.triple.attrs) > 0 ||
693 687 litem[i].searchSpec.triple.element != 0)) {
694 688 int stat;
695 689
696 690 if (dn == 0)
697 691 dn = findDNs(myself, rv, 1,
698 692 t->objectDN->write.base,
699 693 &numDN);
700 694
701 695 stat = storeLDAP(&litem[i], i, numItems, rval,
702 696 t->objectDN, dn, numDN);
703 697 if (stat != LDAP_SUCCESS) {
704 698 char *iname = "<unknown>";
705 699
706 700 if (tmpval != 0 &&
707 701 tmpval->numVals == 1)
708 702 iname = tmpval->val[0].value;
709 703 logmsg(MSG_NOTIMECHECK, LOG_ERR,
710 704 "%s: LDAP store \"%s\": %s",
711 705 myself, iname,
712 706 ldap_err2string(stat));
713 707 }
714 708
715 709 freeValue(tmpval, 1);
716 710 continue;
717 711 }
718 712
719 713 old = lval;
720 714 lval = concatenateValues(old, tmpval);
721 715 freeValue(tmpval, 1);
722 716 freeValue(old, 1);
723 717 }
724 718
725 719 /* Don't need the LHS items themselves anymore */
726 720 freeMappingItem(litem, numItems);
727 721
728 722 /*
729 723 * If we don't have an 'lval' (probably because all litem[i]:s
730 724 * were out-of-context assignments), we're done.
731 725 */
732 726 if (lval == 0 || lval->numVals <= 0) {
733 727 freeValue(lval, 1);
734 728 freeValue(rval, 1);
735 729 return (rv);
736 730 }
737 731
↓ open down ↓ |
105 lines elided |
↑ open up ↑ |
738 732 for (i = 0, j = 0; i < lval->numVals; i++) {
739 733 /* Special case: rval->numVals < 0 means deletion */
740 734 if (rval->numVals < 0) {
741 735 (void) addAttr2RuleValue(rval->type,
742 736 lval->val[i].value, 0, 0, rv);
743 737 continue;
744 738 }
745 739 /* If we're out of values, repeat the last one */
746 740 if (j >= rval->numVals)
747 741 j = (rval->numVals > 0) ? rval->numVals-1 : 0;
748 - for (0; j < rval->numVals; j++) {
742 + for (; j < rval->numVals; j++) {
749 743 /*
750 744 * If this is the 'dn', and the value ends in a
751 745 * comma, append the appropriate search base.
752 746 */
753 747 if (strcasecmp("dn", lval->val[i].value) == 0 &&
754 748 lastChar(&rval->val[j]) == ',' &&
755 749 t->objectDN->write.scope !=
756 750 LDAP_SCOPE_UNKNOWN) {
757 751 void *nval;
758 752 int nlen = -1;
759 753
760 754 nval = appendString2SingleVal(
761 755 t->objectDN->write.base, &rval->val[j],
762 756 &nlen);
763 757 if (nval != 0 && nlen >= 0) {
764 758 sfree(rval->val[j].value);
765 759 rval->val[j].value = nval;
766 760 rval->val[j].length = nlen;
767 761 }
768 762 }
769 763 (void) addAttr2RuleValue(rval->type,
770 764 lval->val[i].value, rval->val[j].value,
771 765 rval->val[j].length, rv);
772 766 /*
773 767 * If the lval is multi-valued, go on to the
774 768 * other values; otherwise, quit (but increment
775 769 * the 'rval' value index).
776 770 */
777 771 if (!lval->repeat) {
778 772 j++;
779 773 break;
780 774 }
781 775 }
782 776 }
783 777
784 778 /* Clean up */
785 779 freeValue(lval, 1);
786 780 freeValue(rval, 1);
787 781
788 782 return (rv);
789 783 }
790 784
791 785 /*
792 786 * Remove the indicated attribute, and any values for it, from the
793 787 * rule-value.
794 788 */
795 789 void
796 790 delAttrFromRuleValue(__nis_rule_value_t *rv, char *attrName) {
797 791 int i;
798 792
799 793 if (rv == 0 || attrName == 0)
800 794 return;
801 795
802 796 for (i = 0; i < rv->numAttrs; i++) {
803 797 if (strcasecmp(attrName, rv->attrName[i]) == 0) {
804 798 int j;
805 799
806 800 for (j = 0; j < rv->attrVal[i].numVals; j++)
807 801 sfree(rv->attrVal[i].val[j].value);
808 802 if (rv->attrVal[i].numVals > 0)
809 803 sfree(rv->attrVal[i].val);
810 804
811 805 sfree(rv->attrName[i]);
812 806
813 807 /* Move up the rest of the attribute names/values */
814 808 for (j = i+1; j < rv->numAttrs; j++) {
815 809 rv->attrName[j-1] = rv->attrName[j];
816 810 rv->attrVal[j-1] = rv->attrVal[j];
817 811 }
818 812
819 813 rv->numAttrs -= 1;
820 814
821 815 break;
822 816 }
823 817 }
824 818 }
825 819
826 820 /*
827 821 * Remove the indicated column, and any values for it, from the
828 822 * rule-value.
829 823 */
830 824 void
831 825 delColFromRuleValue(__nis_rule_value_t *rv, char *colName) {
832 826 int i;
833 827
834 828 if (rv == 0 || colName == 0)
835 829 return;
836 830
837 831 for (i = 0; i < rv->numColumns; i++) {
838 832 if (strcmp(colName, rv->colName[i]) == 0) {
839 833 int j;
840 834
841 835 for (j = 0; j < rv->colVal[i].numVals; j++)
842 836 sfree(rv->colVal[i].val[j].value);
843 837 if (rv->colVal[i].numVals > 0)
844 838 sfree(rv->colVal[i].val);
845 839
846 840 sfree(rv->colName[i]);
847 841
848 842 /* Move up the rest of the column names/values */
849 843 for (j = i+1; j < rv->numColumns; j++) {
850 844 rv->colName[j-1] = rv->colName[j];
851 845 rv->colVal[j-1] = rv->colVal[j];
852 846 }
853 847
854 848 rv->numColumns -= 1;
855 849
856 850 break;
857 851 }
858 852 }
859 853 }
860 854
861 855 /*
862 856 * Add the write-mode object classes specified by 'objClassAttrs' to the
863 857 * rule-value 'rv'.
864 858 * If there's an error, 'rv' is deleted, and NULL returned.
865 859 */
866 860 __nis_rule_value_t *
867 861 addObjectClasses(__nis_rule_value_t *rv, char *objClassAttrs) {
868 862 char *filter = 0, **fc = 0;
869 863 int i, nfc = 0;
870 864
871 865 /*
872 866 * Expect to only use this for existing rule-values, so rv == 0 is
873 867 * an error.
874 868 */
875 869 if (rv == 0)
876 870 return (0);
877 871
878 872 /*
879 873 * If 'objClassAttrs' is NULL, we trivially have nothing to do.
880 874 * Assume the caller knows what it's doing, and return success.
881 875 */
882 876 if (objClassAttrs == 0)
883 877 return (rv);
884 878
885 879 /*
886 880 * Make an AND-filter of the object classes, and split into
887 881 * components. (Yes, this is a bit round-about, but leverages
888 882 * existing functions.)
889 883 */
890 884 filter = makeFilter(objClassAttrs);
891 885 if (filter == 0) {
892 886 freeRuleValue(rv, 1);
893 887 return (0);
894 888 }
895 889
896 890 fc = makeFilterComp(filter, &nfc);
897 891 if (fc == 0 || nfc <= 0) {
898 892 free(filter);
899 893 freeRuleValue(rv, 1);
900 894 return (0);
901 895 }
902 896
903 897 /* Add the objectClass attributes to the rule-value */
904 898 for (i = 0; i < nfc; i++) {
905 899 char *name, *value;
906 900
907 901 name = fc[i];
908 902 /* Skip if not of the "name=value" form */
909 903 if ((value = strchr(name, '=')) == 0)
910 904 continue;
911 905
912 906 *value = '\0';
913 907 value++;
914 908
915 909 /* Skip if the attribute name isn't "objectClass" */
916 910 if (strcasecmp("objectClass", name) != 0)
917 911 continue;
918 912
919 913 if (addSAttr2RuleValue(name, value, rv) != 0) {
920 914 free(filter);
921 915 freeFilterComp(fc, nfc);
922 916 freeRuleValue(rv, 1);
923 917 return (0);
924 918 }
925 919 }
926 920
927 921 free(filter);
928 922 freeFilterComp(fc, nfc);
929 923
930 924 return (rv);
931 925 }
932 926
933 927
934 928 static char *
935 929 valString(__nis_value_t *val) {
936 930 int i;
937 931
938 932 if (val == 0 || val->type != vt_string)
939 933 return (0);
940 934
941 935 for (i = 0; i < val->numVals; i++) {
942 936 /* Look for a non-NULL, non-zero length value */
943 937 if (val->val[i].value != 0 && val->val[i].length > 0) {
944 938 char *v = val->val[i].value;
945 939
946 940 /*
947 941 * Check that there's a NUL at the end. True,
948 942 * if there isn't, we may be looking beyond
949 943 * allocated memory. However, we would have done
950 944 * so in any case when the supposed string was
951 945 * traversed (printed, etc.), very possibly by
952 946 * a lot more than one byte. So, it's better to
953 947 * take a small risk here than a large one later.
954 948 */
955 949 if (v[val->val[i].length-1] == '\0' ||
956 950 v[val->val[i].length] == '\0')
957 951 return (v);
958 952 }
959 953 }
960 954
961 955 return (0);
962 956 }
963 957
964 958 char *
965 959 findVal(char *name, __nis_rule_value_t *rv, __nis_mapping_item_type_t type) {
966 960 int i;
967 961
968 962 if (type == mit_nisplus) {
969 963 for (i = 0; i < rv->numColumns; i++) {
970 964 if (rv->colName[i] == 0)
971 965 continue;
972 966 if (strcmp(name, rv->colName[i]) == 0) {
973 967 return (valString(&rv->colVal[i]));
974 968 }
975 969 }
976 970 } else if (type == mit_ldap) {
977 971 for (i = 0; i < rv->numAttrs; i++) {
978 972 if (rv->attrName[i] == 0)
979 973 continue;
980 974 if (strcasecmp(name, rv->attrName[i]) == 0) {
981 975 return (valString(&rv->attrVal[i]));
982 976 }
983 977 }
984 978 }
985 979
986 980 return (0);
987 981 }
988 982
989 983 static char *norv = "<NIL>";
990 984 static char *unknown = "<unknown>";
991 985
992 986 /*
993 987 * Attempt to derive a string identifying the rule-value 'rv'. The
994 988 * returned string is a pointer, either into 'rv', or to static
995 989 * storage, and must not be freed.
996 990 */
997 991 char *
998 992 rvId(__nis_rule_value_t *rv, __nis_mapping_item_type_t type) {
999 993 char *v;
1000 994
1001 995 if (rv == 0)
1002 996 return (norv);
1003 997
1004 998 if (rv->numColumns > 0 && type == mit_nisplus) {
1005 999 /*
1006 1000 * Look for a column called "cname" or "name".
1007 1001 * If that fails, try "key" or "alias".
1008 1002 */
1009 1003 if ((v = findVal("cname", rv, type)) != 0)
1010 1004 return (v);
1011 1005 else if ((v = findVal("name", rv, type)) != 0)
1012 1006 return (v);
1013 1007 else if ((v = findVal("key", rv, type)) != 0)
1014 1008 return (v);
1015 1009 else if ((v = findVal("alias", rv, type)) != 0)
1016 1010 return (v);
1017 1011 } else if (rv->numAttrs > 0 && type == mit_ldap) {
1018 1012 /*
1019 1013 * Look for "dn", or "cn".
1020 1014 */
1021 1015 if ((v = findVal("dn", rv, type)) != 0)
1022 1016 return (v);
1023 1017 else if ((v = findVal("cn", rv, type)) != 0)
1024 1018 return (v);
1025 1019 }
1026 1020
1027 1021 return (unknown);
1028 1022 }
1029 1023
1030 1024 /*
1031 1025 * Merge the rule-values with the same DN into one. Each rule-value
1032 1026 * in the returned array will have unique 'dn'. On entry, *numVals
1033 1027 * contains the number of rule-values in 'rv'. On exit, it contains
1034 1028 * the number of rule-values in the returned array or -1 on error.
1035 1029 */
1036 1030 __nis_rule_value_t *
1037 1031 mergeRuleValueWithSameDN(__nis_rule_value_t *rv, int *numVals) {
1038 1032 __nis_rule_value_t *rvq = 0;
1039 1033 char *dn, *odn;
1040 1034 int count = 0;
1041 1035 int i, j;
1042 1036
1043 1037 if (numVals == 0)
1044 1038 return (0);
1045 1039
1046 1040 for (i = 0; i < *numVals; i++) {
1047 1041 if ((dn = findVal("dn", &rv[i], mit_ldap)) != 0) {
1048 1042 for (j = 0; j < count; j++) {
1049 1043 if ((odn = findVal("dn", &rvq[j],
1050 1044 mit_ldap)) != 0) {
1051 1045 /* case sensitive compare */
1052 1046 if (strcmp(dn, odn) != 0)
1053 1047 continue;
1054 1048 if (mergeRuleValue(&rvq[j],
1055 1049 &rv[i]) == -1) {
1056 1050 freeRuleValue(rvq, count);
1057 1051 *numVals = -1;
1058 1052 return (0);
1059 1053 }
1060 1054 break;
1061 1055 } else {
1062 1056 freeRuleValue(rvq, count);
1063 1057 *numVals = -1;
1064 1058 return (0);
1065 1059 }
1066 1060 }
1067 1061 /* if no match, then add it to the rulevalue array */
1068 1062 if (j == count) {
1069 1063 rvq = growRuleValue(count, count + 1, rvq,
1070 1064 &rv[i]);
1071 1065 if (rvq == 0) {
1072 1066 *numVals = -1;
1073 1067 return (0);
1074 1068 }
1075 1069 count++;
1076 1070 }
1077 1071 }
1078 1072 }
1079 1073
1080 1074 *numVals = count;
1081 1075 return (rvq);
1082 1076 }
↓ open down ↓ |
324 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX