1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <ctype.h> 30 #include <libintl.h> 31 #include <strings.h> 32 #include <stdio.h> 33 #include "../../../lib/libsldap/common/ns_sldap.h" 34 35 36 #define MAXLINE 2000 37 #define SAME 0 38 39 struct mapping { 40 char *database; 41 char *def_type; 42 char *objectclass; 43 char *actual_db; 44 }; 45 46 #define PUBLICKEY 0 47 48 static struct mapping maplist[] = { 49 {"publickey", "uidnumber", "niskeyobject", "passwd"}, 50 {"publickey", "cn", "niskeyobject", "host"}, 51 {"bootparams", "cn", "bootableDevice", NULL}, 52 {"ethers", "cn", "ieee802Device", NULL}, 53 {"group", "cn", "posixgroup", NULL}, 54 {"hosts", "cn", "iphost", NULL}, 55 {"ipnodes", "cn", "iphost", NULL}, 56 {"netgroup", "cn", "nisnetgroup", NULL}, 57 {"netmasks", "ipnetworknumber", "ipnetwork", NULL}, 58 {"networks", "ipnetworknumber", "ipnetwork", NULL}, 59 {"passwd", "uid", "posixaccount", NULL}, 60 {"protocols", "cn", "ipprotocol", NULL}, 61 {"rpc", "cn", "oncrpc", NULL}, 62 {"services", "cn", "ipservice", NULL}, 63 {"aliases", "cn", "mailGroup", NULL}, 64 {"project", "SolarisProjectID", "SolarisProject", NULL}, 65 {"printers", "printer-uri", "sunPrinter", NULL}, 66 {"shadow", "uid", "shadowaccount", NULL}, 67 {"auth_attr", "cn", "SolarisAuthAttr", NULL}, 68 {"prof_attr", "cn", "SolarisProfAttr", NULL}, 69 {"exec_attr", "cn", "SolarisExecAttr", NULL}, 70 {"user_attr", "uid", "SolarisUserAttr", NULL}, 71 {"audit_user", "uid", "SolarisAuditUser", NULL}, 72 {NULL, NULL, NULL, NULL} 73 }; 74 75 76 void 77 printMapping() 78 { 79 int i; 80 81 fprintf(stdout, 82 gettext("database default type objectclass\n")); 83 fprintf(stdout, 84 gettext("============= ================= =============\n")); 85 /* first dump auto_* and automount which are not in maplist[] */ 86 fprintf(stdout, "%-15s%-20s%s\n", "auto_*", "automountKey", 87 "automount"); 88 fprintf(stdout, "%-15s%-20s%s\n", "automount", "automountMapName", 89 "automountMap"); 90 for (i = 0; maplist[i].database != NULL; i++) { 91 /* skip printing shadow */ 92 if (strcasecmp(maplist[i].database, "shadow") != 0) 93 fprintf(stdout, "%-15s%-20s%s\n", maplist[i].database, 94 maplist[i].def_type, maplist[i].objectclass); 95 } 96 } 97 98 99 char * 100 set_keys(char **key, char *attrtype) 101 { 102 char *keyeq = NULL; 103 static char keyfilter[MAXLINE]; 104 char typeeq[100]; 105 char buf[100]; 106 char *k, **karray; 107 108 if (!key || !key[0]) /* should never contain NULL string */ 109 return (NULL); 110 111 if (attrtype) { 112 strcpy(typeeq, attrtype); 113 strcat(typeeq, "="); 114 } 115 116 keyfilter[0] = '\0'; 117 if (key[1]) 118 strcat(keyfilter, "(|"); 119 karray = key; 120 while (k = *karray) { 121 keyeq = strchr(k, '='); 122 sprintf(buf, "(%s%s)", (keyeq ? "" : typeeq), k); 123 if (strlen(buf) + strlen(keyfilter) >= MAXLINE) { 124 fprintf(stdout, 125 gettext("***ERROR: ldapfilter too long\n")); 126 exit(2); 127 } 128 strcat(keyfilter, buf); 129 karray++; 130 } 131 if (key[1]) 132 strcat(keyfilter, ")"); 133 return (keyfilter); 134 } 135 136 137 /* 138 * A special set_key routine for to handle public keys. 139 * If the key starts with a digiti, view it as a user id. 140 * Otherwise, view it as a hostname. 141 * It returns: -1 no keys defined, 0 key defined but none for type 142 * specified, n>0 number of matches found. 143 */ 144 int 145 set_keys_publickey(char **key, char *attrtype, int type, char **ret) 146 { 147 char *keyeq = NULL; 148 static char keyfilter[MAXLINE]; 149 char pre_filter[MAXLINE]; 150 char buf[100]; 151 char *k, **karray; 152 int count = 0; 153 154 if (!key || !key[0]) { /* should never contain NULL string */ 155 *ret = NULL; 156 return (-1); 157 } 158 159 keyfilter[0] = '\0'; 160 pre_filter[0] = '\0'; 161 karray = key; 162 while (k = *karray) { 163 keyeq = strchr(k, '='); 164 if (keyeq) 165 sprintf(buf, "(%s)", k); 166 else { 167 if (type == 0 && isdigit(*k)) { 168 /* user type keys */ 169 sprintf(buf, "(%s=%s)", attrtype, k); 170 } else if (type == 1 && (!isdigit(*k))) { 171 /* hosts type keys */ 172 sprintf(buf, "(%s=%s)", attrtype, k); 173 } else { 174 karray++; 175 continue; 176 } 177 } 178 if (strlen(buf) + strlen(pre_filter) >= MAXLINE) { 179 fprintf(stdout, 180 gettext("***ERROR: ldapfilter too long\n")); 181 exit(2); 182 } 183 strcat(pre_filter, buf); 184 karray++; 185 count++; 186 } 187 if (count > 1) { 188 if (strlen(pre_filter) + 4 >= MAXLINE) { 189 fprintf(stdout, 190 gettext("***ERROR: ldapfilter too long\n")); 191 exit(2); 192 } 193 strcat(keyfilter, "(|"); 194 strcat(keyfilter, pre_filter); 195 strcat(keyfilter, ")"); 196 *ret = keyfilter; 197 } else 198 *ret = pre_filter; 199 return (count); 200 } 201 202 /* 203 * publickey specific set_filter 204 * type 0 -> check for user publickeys 205 * type 1 -> check for hosts publickeys 206 */ 207 char * 208 set_filter_publickey(char **key, char *database, int type, char **udata) 209 { 210 char *filter; 211 char *userdata; 212 char *keyfilter; 213 int rc; 214 215 if (!database) { 216 return (NULL); 217 } 218 if (!udata) { 219 return (NULL); 220 } 221 222 filter = (char *)malloc(MAXLINE); 223 if (!filter) { 224 return (NULL); 225 } 226 filter[0] = '\0'; 227 228 userdata = (char *)malloc(MAXLINE); 229 if (!userdata) { 230 free(filter); 231 return (NULL); 232 } 233 userdata[0] = '\0'; 234 *udata = userdata; 235 236 if (strcasecmp(database, maplist[PUBLICKEY].database) == SAME) { 237 rc = set_keys_publickey(key, 238 maplist[PUBLICKEY + type].def_type, type, 239 &keyfilter); 240 switch (rc) { 241 case -1: 242 sprintf(filter, "objectclass=%s", 243 maplist[PUBLICKEY].objectclass); 244 sprintf(userdata, "%%s"); 245 break; 246 case 0: 247 return (NULL); 248 default: 249 sprintf(filter, "(&(objectclass=%s)%s)", 250 maplist[PUBLICKEY].objectclass, keyfilter); 251 sprintf(userdata, "(&(%%s)%s)", 252 keyfilter); 253 } 254 } else { 255 if ((keyfilter = set_keys(key, "cn")) == NULL) { 256 sprintf(filter, "objectclass=*"); 257 sprintf(userdata, "%%s"); 258 } else { 259 sprintf(filter, "%s", keyfilter); 260 sprintf(userdata, "(&(%%s)%s)", keyfilter); 261 } 262 } 263 #ifdef DEBUG 264 fprintf(stdout, "set_filter: filter=\"%s\"\n", filter); 265 fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata); 266 #endif /* DEBUG */ 267 return (filter); 268 } 269 270 271 /* generic set_filter, this function is not thread safe */ 272 char * 273 set_filter(char **key, char *database, char **udata) 274 { 275 char *filter; 276 char *userdata; 277 char *keyfilter; 278 int i; 279 int rc, v2 = 1; 280 void **paramVal = NULL; 281 ns_ldap_error_t *errorp = NULL; 282 283 if (!database) { 284 return (NULL); 285 } 286 if (!udata) { 287 return (NULL); 288 } 289 290 filter = (char *)malloc(MAXLINE); 291 if (!filter) { 292 return (NULL); 293 } 294 filter[0] = '\0'; 295 296 userdata = (char *)malloc(MAXLINE); 297 if (!userdata) { 298 free(filter); 299 return (NULL); 300 } 301 userdata[0] = '\0'; 302 *udata = userdata; 303 304 /* 305 * Check for version of the profile the client is using 306 * 307 * For version 1 profiles we do use nisMap and nisObject schema 308 * for backward compatibility with Solaris 8 clients. 309 * 310 * For version 2 profiles we use automountMap and automount as 311 * default attributes (which can then be overridden in libsldap 312 * if schema mapping is configured in the profile). 313 * 314 * If profile version is not available, use version 2 as default. 315 */ 316 rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, ¶mVal, &errorp); 317 if (rc != NS_LDAP_SUCCESS || !paramVal || !*paramVal) { 318 /* should print a message here: using v2 defaults */ 319 (void) __ns_ldap_freeError(&errorp); 320 } else { 321 if (strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0) 322 v2 = 0; 323 (void) __ns_ldap_freeParam(¶mVal); 324 } 325 326 /* 327 * starts at 2 to skip over publickey databases. 328 * These databases are handled separately. 329 */ 330 for (i = 2; maplist[i].database != NULL; i++) { 331 if (strcasecmp(database, maplist[i].database) == SAME) { 332 if ((keyfilter = set_keys(key, maplist[i].def_type)) 333 == NULL) { 334 snprintf(filter, MAXLINE, "objectclass=%s", 335 maplist[i].objectclass); 336 sprintf(userdata, "%%s"); 337 } else { 338 snprintf(filter, MAXLINE, 339 "(&(objectclass=%s)%s)", 340 maplist[i].objectclass, keyfilter); 341 snprintf(userdata, MAXLINE, "(&(%%s)%s)", 342 keyfilter); 343 #ifdef DEBUG 344 fprintf(stdout, "set_filter: filter=\"%s\"\n", filter); 345 fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata); 346 #endif /* DEBUG */ 347 } 348 return (filter); 349 } 350 } 351 352 /* special cases for automounter and other services */ 353 354 /* auto_* services */ 355 if (strncasecmp(database, "auto_", 5) == SAME) { 356 if (v2) { 357 if ((keyfilter = set_keys(key, "automountKey")) 358 != NULL) { 359 snprintf(filter, MAXLINE, 360 "(&(objectclass=automount)%s)", keyfilter); 361 snprintf(userdata, MAXLINE, "(&(%%s)%s)", keyfilter); 362 } else { 363 strcpy(filter, "objectclass=automount"); 364 strcpy(userdata, "%s"); 365 } 366 } else { 367 if ((keyfilter = set_keys(key, "cn")) 368 != NULL) { 369 snprintf(filter, MAXLINE, 370 "(&(objectclass=nisObject)%s)", keyfilter); 371 snprintf(userdata, MAXLINE, "(&(%%s)%s)", keyfilter); 372 } else { 373 strcpy(filter, "objectclass=nisObject"); 374 strcpy(userdata, "%s"); 375 } 376 } 377 goto done; 378 } 379 380 /* automount service */ 381 if (strcasecmp(database, "automount") == SAME) { 382 if (v2) { 383 if ((keyfilter = set_keys(key, "automountMapName")) 384 != NULL) { 385 snprintf(filter, MAXLINE, 386 "(&(objectclass=automountMap)%s)", keyfilter); 387 snprintf(userdata, MAXLINE, "(&(%%s)%s)", keyfilter); 388 } else { 389 strcpy(filter, "objectclass=automountMap"); 390 strcpy(userdata, "%s"); 391 } 392 } else { 393 if ((keyfilter = set_keys(key, "nisMapName")) 394 != NULL) { 395 snprintf(filter, MAXLINE, "(&(objectclass=nisMap)%s)", 396 keyfilter); 397 snprintf(userdata, MAXLINE, "(&(%%s)%s)", keyfilter); 398 } else { 399 strcpy(filter, "objectclass=nisMap"); 400 strcpy(userdata, "%s"); 401 } 402 } 403 goto done; 404 } 405 406 /* other services (catch all) */ 407 if ((keyfilter = set_keys(key, "cn")) == NULL) { 408 snprintf(filter, MAXLINE, "objectclass=*"); 409 strcpy(userdata, "%s"); 410 } else { 411 snprintf(filter, MAXLINE, "%s", keyfilter); 412 snprintf(userdata, MAXLINE, "(&(%%s)(%s))", keyfilter); 413 } 414 415 done: 416 #ifdef DEBUG 417 fprintf(stdout, "set_filter: filter=\"%s\"\n", filter); 418 fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata); 419 #endif /* DEBUG */ 420 return (filter); 421 } 422