dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / ldap / ns_ldap / mapping.c
blob077ee78f4057b7647a1591c80966b375a50acafa
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <ctype.h>
27 #include <libintl.h>
28 #include <strings.h>
29 #include <stdio.h>
30 #include "../../../lib/libsldap/common/ns_sldap.h"
33 #define SAME 0
35 struct mapping {
36 char *database;
37 char *def_type;
38 char *objectclass;
39 char *actual_db;
42 #define PUBLICKEY 0
44 static struct mapping maplist[] = {
45 {"publickey", "uidnumber", "niskeyobject", "passwd"},
46 {"publickey", "cn", "niskeyobject", "host"},
47 {"bootparams", "cn", "bootableDevice", NULL},
48 {"ethers", "cn", "ieee802Device", NULL},
49 {"group", "cn", "posixgroup", NULL},
50 {"hosts", "cn", "iphost", NULL},
51 {"ipnodes", "cn", "iphost", NULL},
52 {"netgroup", "cn", "nisnetgroup", NULL},
53 {"netmasks", "ipnetworknumber", "ipnetwork", NULL},
54 {"networks", "ipnetworknumber", "ipnetwork", NULL},
55 {"passwd", "uid", "posixaccount", NULL},
56 {"protocols", "cn", "ipprotocol", NULL},
57 {"rpc", "cn", "oncrpc", NULL},
58 {"services", "cn", "ipservice", NULL},
59 {"aliases", "cn", "mailGroup", NULL},
60 {"project", "SolarisProjectID", "SolarisProject", NULL},
61 {"printers", "printer-uri", "sunPrinter", NULL},
62 {"shadow", "uid", "shadowaccount", NULL},
63 {"auth_attr", "cn", "SolarisAuthAttr", NULL},
64 {"prof_attr", "cn", "SolarisProfAttr", NULL},
65 {"exec_attr", "cn", "SolarisExecAttr", NULL},
66 {"user_attr", "uid", "SolarisUserAttr", NULL},
67 {NULL, NULL, NULL, NULL}
70 #define PROF_ATTR_FILTER \
71 "(&(objectclass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*))%s)"
72 #define OC_FILTER "objectclass=%s"
73 #define OC_FLEN 15
74 #define OC_FILTER2 "(&(objectclass=%s)%s)"
75 #define OC_FLEN2 22
77 /* Malloc and print error message in case of failure */
78 #define MALLOC(ptr, len) \
79 if ((ptr = (char *)malloc(len)) == NULL) { \
80 (void) fprintf(stderr, gettext("out of memory\n")); \
84 * Allocate memory for filter and user data. Set
85 * error to 1 if either of the mallocs fail.
86 * In addition, free the memory allocated for filter,
87 * if memory allocation for user data fails.
89 #define MALLOC_FILTER_UDATA(ptr1, len1, ptr2, len2, error) \
90 error = 0; \
91 MALLOC(ptr1, len1); \
92 if (!ptr1) { \
93 error = 1; \
94 } \
95 else { \
96 MALLOC(ptr2, len2); \
97 if (!ptr2) { \
98 error = 1; \
99 free(ptr1); \
103 void
104 printMapping()
106 int i;
108 (void) fprintf(stdout,
109 gettext("database default type objectclass\n"));
110 (void) fprintf(stdout,
111 gettext("============= ================= =============\n"));
112 /* first dump auto_* and automount which are not in maplist[] */
113 (void) fprintf(stdout, "%-15s%-20s%s\n", "auto_*", "automountKey",
114 "automount");
115 (void) fprintf(stdout, "%-15s%-20s%s\n", "automount",
116 "automountMapName", "automountMap");
117 for (i = 0; maplist[i].database != NULL; i++) {
118 /* skip printing shadow */
119 if (strcasecmp(maplist[i].database, "shadow") == 0)
120 continue;
121 (void) fprintf(stdout, "%-15s%-20s%s\n", maplist[i].database,
122 maplist[i].def_type, maplist[i].objectclass);
127 * set_key routine to handle user specified keys.
128 * A key can be of the form: attribute=value or value.
129 * A filter is constructed from a set of keys specified in
130 * the form (|(key1)(key2)...(keyn))
131 * It returns: NULL if no keys are defined or
132 * the keyfilter as constructed above.
135 char *
136 set_keys(char **key, char *attrtype)
138 char *keyeq = NULL;
139 char *keyfilter = NULL;
140 int len, totlen = 1; /* Terminating NULL byte */
141 char *k, **karray;
142 char *tmpptr;
144 if (!key || !key[0]) /* should never contain NULL string */
145 return (NULL);
147 if (key[1]) {
148 totlen += 3;
149 /* Allocate memory for '(|)' */
150 MALLOC(keyfilter, totlen);
151 if (!keyfilter)
152 exit(2);
153 (void) snprintf(keyfilter, totlen, "(|");
156 karray = key;
157 while ((k = *karray) != 0) {
158 keyeq = strchr(k, '=');
159 if (keyeq) {
160 /* make enough room for (%s) */
161 totlen += strlen(k) + 2;
162 } else {
163 /* make enough room for (%s=%s) */
164 totlen += strlen(attrtype) + strlen(k) + 3;
167 len = keyfilter ? strlen(keyfilter) : 0;
169 if (!(tmpptr = (char *)realloc(keyfilter, totlen))) {
170 free(keyfilter);
171 (void) fprintf(stderr, gettext("out of memory\n"));
172 exit(2);
174 keyfilter = tmpptr;
176 if (keyeq) {
177 (void) snprintf(keyfilter + len, totlen - len,
178 "(%s)", k);
179 } else {
180 (void) snprintf(keyfilter + len, totlen - len,
181 "(%s=%s)", attrtype, k);
183 karray++;
186 if (key[1]) {
187 /* We allocated memory for this earlier */
188 (void) strlcat(keyfilter, ")", totlen);
191 return (keyfilter);
196 * A special set_key routine for to handle public keys.
197 * If the key starts with a digiti, view it as a user id.
198 * Otherwise, view it as a hostname.
199 * It returns: -1 no keys defined, 0 key defined but none for type
200 * specified, n>0 number of matches found.
203 set_keys_publickey(char **key, char *attrtype, int type, char **ret)
205 char *keyeq = NULL;
206 char *keyfilter = NULL;
207 char *pre_filter = NULL;
208 char *k, **karray;
209 int count = 0;
210 int len, totlen = 1; /* Terminating NULL byte */
211 char *tmpptr;
213 if (!key || !key[0]) { /* should never contain NULL string */
214 *ret = NULL;
215 return (-1);
218 karray = key;
219 while ((k = *karray) != 0) {
220 keyeq = strchr(k, '=');
221 if (keyeq) {
222 /* make enough room for (%s) */
223 totlen += strlen(k) + 2;
224 } else {
225 if ((type == 0 && isdigit(*k)) ||
226 /* user type keys */
227 (type == 1 && (!isdigit(*k)))) {
228 /* hosts type keys */
229 /* make enough room for (%s=%s) */
230 totlen += strlen(k) + strlen(attrtype) + 3;
231 } else {
232 karray++;
233 continue;
237 len = pre_filter ? strlen(pre_filter) : 0;
239 if (!(tmpptr = (char *)realloc(pre_filter, totlen))) {
240 free(pre_filter);
241 (void) fprintf(stderr, gettext("out of memory\n"));
242 exit(2);
244 pre_filter = tmpptr;
246 if (keyeq) {
247 (void) snprintf(pre_filter + len, totlen - len,
248 "(%s)", k);
249 } else {
250 (void) snprintf(pre_filter + len, totlen - len,
251 "(%s=%s)", attrtype, k);
253 karray++;
254 count++;
256 if (count > 1) {
257 len = strlen(pre_filter) + 4;
258 if (!(keyfilter = (char *)malloc(len))) {
259 (void) fprintf(stderr, gettext("out of memory\n"));
260 free(pre_filter);
261 exit(2);
263 (void) snprintf(keyfilter, len, "(|%s)", pre_filter);
264 free(pre_filter);
265 *ret = keyfilter;
266 } else
267 *ret = pre_filter;
268 return (count);
272 * publickey specific set_filter
273 * type 0 -> check for user publickeys
274 * type 1 -> check for hosts publickeys
276 char *
277 set_filter_publickey(char **key, char *database, int type, char **udata)
279 char *filter = NULL;
280 char *userdata;
281 char *keyfilter = NULL;
282 int rc;
283 int filterlen, udatalen;
284 short nomem = 0;
286 if (!database || !udata) {
287 return (NULL);
290 if (strcasecmp(database, maplist[PUBLICKEY].database) == SAME) {
291 rc = set_keys_publickey(key,
292 maplist[PUBLICKEY + type].def_type, type, &keyfilter);
293 switch (rc) {
294 case -1:
295 filterlen = strlen(maplist[PUBLICKEY].objectclass) + 13;
296 udatalen = 3;
297 MALLOC_FILTER_UDATA(filter, filterlen, userdata,
298 udatalen, nomem);
299 if (!nomem) {
300 (void) snprintf(filter, filterlen,
301 "objectclass=%s",
302 maplist[PUBLICKEY].objectclass);
303 (void) snprintf(userdata, udatalen, "%%s");
305 break;
306 case 0:
307 return (NULL);
308 default:
309 filterlen = strlen(maplist[PUBLICKEY].objectclass) +
310 strlen(keyfilter) + 18;
311 udatalen = strlen(keyfilter) + 8;
312 MALLOC_FILTER_UDATA(filter, filterlen, userdata,
313 udatalen, nomem);
314 if (!nomem) {
315 (void) snprintf(filter, filterlen,
316 "(&(objectclass=%s)%s)",
317 maplist[PUBLICKEY].objectclass, keyfilter);
318 (void) snprintf(userdata, udatalen,
319 "(&(%%s)%s)", keyfilter);
322 } else {
323 if ((keyfilter = set_keys(key, "cn")) == NULL) {
324 filterlen = 14;
325 udatalen = 3;
326 MALLOC_FILTER_UDATA(filter, filterlen, userdata,
327 udatalen, nomem);
328 if (!nomem) {
329 (void) snprintf(filter, filterlen,
330 "objectclass=*");
331 (void) snprintf(userdata, udatalen, "%%s");
333 } else {
334 filterlen = strlen(keyfilter) + 1;
335 udatalen = strlen(keyfilter) + 8;
336 MALLOC_FILTER_UDATA(filter, filterlen, userdata,
337 udatalen, nomem);
338 if (!nomem) {
339 (void) snprintf(filter, filterlen, "%s",
340 keyfilter);
341 (void) snprintf(userdata, udatalen,
342 "(&(%%s)%s)", keyfilter);
346 #ifdef DEBUG
347 (void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
348 (void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
349 #endif /* DEBUG */
350 free(keyfilter);
351 if (nomem)
352 exit(2);
353 *udata = userdata;
354 return (filter);
358 /* generic set_filter, this function is not thread safe */
359 char *
360 set_filter(char **key, char *database, char **udata)
362 char *filter = NULL;
363 char *userdata = NULL;
364 char *keyfilter;
365 int i, filterlen, udatalen;
366 int rc, v2 = 1;
367 int dbpf;
368 void **paramVal = NULL;
369 ns_ldap_error_t *errorp = NULL;
370 short nomem;
372 if (!database || !udata) {
373 return (NULL);
378 * Check for version of the profile the client is using
380 * For version 1 profiles we do use nisMap and nisObject schema
381 * for backward compatibility with Solaris 8 clients.
383 * For version 2 profiles we use automountMap and automount as
384 * default attributes (which can then be overridden in libsldap
385 * if schema mapping is configured in the profile).
387 * If profile version is not available, use version 2 as default.
389 rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal, &errorp);
390 if (rc != NS_LDAP_SUCCESS || !paramVal || !*paramVal) {
391 /* should print a message here: using v2 defaults */
392 (void) __ns_ldap_freeError(&errorp);
393 } else {
394 if (strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
395 v2 = 0;
396 (void) __ns_ldap_freeParam(&paramVal);
400 * starts at 2 to skip over publickey databases.
401 * These databases are handled separately.
403 for (i = 2; maplist[i].database != NULL; i++) {
404 if (strcasecmp(database, maplist[i].database) == SAME) {
405 dbpf = 0;
406 if (strcasecmp(database, "prof_attr") == 0)
407 dbpf = 1;
408 if ((keyfilter = set_keys(key, maplist[i].def_type))
409 == NULL) {
410 filterlen = strlen(maplist[i].objectclass);
411 udatalen = 3;
412 if (dbpf)
413 filterlen += strlen(PROF_ATTR_FILTER)
414 + 1;
415 else
416 filterlen += OC_FLEN;
418 MALLOC_FILTER_UDATA(filter, filterlen, userdata,
419 udatalen, nomem);
420 if (nomem)
421 goto done;
422 if (dbpf)
423 (void) snprintf(filter, filterlen,
424 PROF_ATTR_FILTER, "");
425 else
426 (void) snprintf(filter, filterlen,
427 OC_FILTER,
428 maplist[i].objectclass);
430 (void) snprintf(userdata, udatalen, "%%s");
431 } else {
432 filterlen = strlen(maplist[i].objectclass) +
433 strlen(keyfilter);
434 if (dbpf)
435 filterlen += strlen(PROF_ATTR_FILTER)
436 + 1;
437 else
438 filterlen += OC_FLEN2;
440 udatalen = strlen(keyfilter) + 8;
441 MALLOC_FILTER_UDATA(filter, filterlen, userdata,
442 udatalen, nomem);
443 if (nomem)
444 goto done;
445 if (dbpf)
446 (void) snprintf(filter, filterlen,
447 PROF_ATTR_FILTER, keyfilter);
448 else
449 (void) snprintf(filter, filterlen,
450 OC_FILTER2,
451 maplist[i].objectclass, keyfilter);
453 (void) snprintf(userdata, udatalen,
454 "(&(%%s)%s)", keyfilter);
456 goto done;
460 /* special cases for automounter and other services */
462 /* auto_* services */
463 if (strncasecmp(database, "auto_", 5) == SAME) {
464 if (v2) {
465 if ((keyfilter = set_keys(key, "automountKey"))
466 != NULL) {
467 filterlen = strlen(keyfilter) + 27;
468 udatalen = strlen(keyfilter) + 8;
469 MALLOC_FILTER_UDATA(filter, filterlen,
470 userdata, udatalen, nomem);
471 if (!nomem) {
472 (void) snprintf(filter, filterlen,
473 "(&(objectclass=automount)%s)",
474 keyfilter);
475 (void) snprintf(userdata, udatalen,
476 "(&(%%s)%s)", keyfilter);
478 } else {
479 filterlen = 22;
480 udatalen = 3;
481 MALLOC_FILTER_UDATA(filter, filterlen,
482 userdata, udatalen, nomem);
483 if (!nomem) {
484 (void) strlcpy(filter,
485 "objectclass=automount", filterlen);
486 (void) strlcpy(userdata, "%s",
487 udatalen);
490 } else {
491 if ((keyfilter = set_keys(key, "cn")) != NULL) {
492 filterlen = strlen(keyfilter) + 27;
493 udatalen = strlen(keyfilter) + 8;
494 MALLOC_FILTER_UDATA(filter, filterlen,
495 userdata, udatalen, nomem);
496 if (!nomem) {
497 (void) snprintf(filter, filterlen,
498 "(&(objectclass=nisObject)%s)",
499 keyfilter);
500 (void) snprintf(userdata, udatalen,
501 "(&(%%s)%s)", keyfilter);
503 } else {
504 filterlen = 22;
505 udatalen = 3;
506 MALLOC_FILTER_UDATA(filter, filterlen,
507 userdata, udatalen, nomem);
508 if (!nomem) {
509 (void) strlcpy(filter,
510 "objectclass=nisObject", filterlen);
511 (void) strlcpy(userdata, "%s",
512 udatalen);
516 goto done;
519 /* automount service */
520 if (strcasecmp(database, "automount") == SAME) {
521 if (v2) {
522 if ((keyfilter = set_keys(key, "automountMapName"))
523 != NULL) {
524 filterlen = strlen(keyfilter) + 30;
525 udatalen = strlen(keyfilter) + 8;
526 MALLOC_FILTER_UDATA(filter, filterlen,
527 userdata, udatalen, nomem);
528 if (!nomem) {
529 (void) snprintf(filter, filterlen,
530 "(&(objectclass=automountMap)%s)",
531 keyfilter);
532 (void) snprintf(userdata, udatalen,
533 "(&(%%s)%s)", keyfilter);
535 } else {
536 filterlen = 25;
537 udatalen = 3;
538 MALLOC_FILTER_UDATA(filter, filterlen,
539 userdata, udatalen, nomem);
540 if (!nomem) {
541 (void) strlcpy(filter,
542 "objectclass=automountMap",
543 filterlen);
544 (void) strlcpy(userdata, "%s",
545 udatalen);
548 } else {
549 if ((keyfilter = set_keys(key, "nisMapName"))
550 != NULL) {
551 filterlen = strlen(keyfilter) + 24;
552 udatalen = strlen(keyfilter) + 8;
553 MALLOC_FILTER_UDATA(filter, filterlen,
554 userdata, udatalen, nomem);
555 if (!nomem) {
556 (void) snprintf(filter, filterlen,
557 "(&(objectclass=nisMap)%s)",
558 keyfilter);
559 (void) snprintf(userdata, udatalen,
560 "(&(%%s)%s)", keyfilter);
562 } else {
563 filterlen = 19;
564 udatalen = 3;
565 MALLOC_FILTER_UDATA(filter, filterlen,
566 userdata, udatalen, nomem);
567 if (!nomem) {
568 (void) strlcpy(filter,
569 "objectclass=nisMap", filterlen);
570 (void) strlcpy(userdata, "%s",
571 udatalen);
575 goto done;
578 /* other services (catch all) */
579 if ((keyfilter = set_keys(key, "cn")) == NULL) {
580 filterlen = 14;
581 udatalen = 3;
582 MALLOC_FILTER_UDATA(filter, filterlen, userdata, udatalen,
583 nomem);
584 if (!nomem) {
585 (void) snprintf(filter, filterlen, "objectclass=*");
586 (void) strlcpy(userdata, "%s", udatalen);
588 } else {
589 filterlen = strlen(keyfilter) + 1;
590 udatalen = strlen(keyfilter) + 8;
591 MALLOC_FILTER_UDATA(filter, filterlen, userdata, udatalen,
592 nomem);
593 if (!nomem) {
594 (void) snprintf(filter, filterlen, "%s", keyfilter);
595 (void) snprintf(userdata, udatalen, "(&(%%s)%s)",
596 keyfilter);
600 done:
601 #ifdef DEBUG
602 (void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
603 (void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
604 #endif /* DEBUG */
605 free(keyfilter);
606 if (nomem)
607 exit(2);
608 *udata = userdata;
609 return (filter);