static int __s_api_parseASearchDesc(const char *service, char **cur, ns_ldap_search_desc_t **ret) { ns_ldap_search_desc_t *ptr; char *sptr, *dptr; int i, rc; ns_ldap_error_t **errorp = NULL; ns_ldap_error_t *error = NULL; void **paramVal = NULL; char **dns = NULL; _ns_parse_state_t state = P_INIT; int quoted = 0; int wasquoted = 0; int empty = 1; if (ret == NULL) return (NS_LDAP_INVALID_PARAM); *ret = NULL; if (cur == NULL) return (NS_LDAP_INVALID_PARAM); ptr = (ns_ldap_search_desc_t *) calloc(1, sizeof (ns_ldap_search_desc_t)); if (ptr == NULL) return (NS_LDAP_MEMORY); sptr = *cur; /* Get the default scope */ if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P, ¶mVal, errorp)) != NS_LDAP_SUCCESS) { (void) __ns_ldap_freeError(errorp); __ns_ldap_freeASearchDesc(ptr); ptr = NULL; return (NS_LDAP_MEMORY); } if (paramVal && *paramVal) ptr->scope = * (ScopeType_t *)(*paramVal); else ptr->scope = NS_LDAP_SCOPE_ONELEVEL; (void) __ns_ldap_freeParam(¶mVal); paramVal = NULL; for (/* none */; state != P_EXIT && sptr && *sptr; sptr++) { empty = 0; switch (state) { case P_INIT: if (*sptr == QUESTTOK) { /* No basedn */ ptr->basedn = strdup(""); if (!ptr->basedn) { state = P_MEMERR; break; } state = P_SCOPE; break; } if (*sptr == SEMITOK) { /* No SSD */ ptr->basedn = strdup(""); if (!ptr->basedn) { state = P_MEMERR; break; } state = P_EXIT; break; } /* prepare to copy DN */ i = strlen(sptr) + 1; ptr->basedn = dptr = (char *)calloc(i, sizeof (char)); if (!ptr->basedn) { state = P_MEMERR; break; } if (*sptr == BSLTOK) { if (*(sptr+1) == '\0') { /* error */ state = P_ERROR; break; } if (*(sptr+1) == QUOTETOK || *(sptr+1) == BSLTOK) { /* escaped CHARS */ sptr++; } else { *dptr++ = *sptr++; } *dptr++ = *sptr; } else if (*sptr == QUOTETOK) { quoted = 1; wasquoted = 1; } else { *dptr++ = *sptr; } state = P_BASEDN; break; case P_INIFILTER: if (*sptr == SEMITOK) { /* No filter and no more SSD */ state = P_EXIT; break; } /* prepare to copy DN */ i = strlen(sptr) + 1; ptr->filter = dptr = (char *)calloc(i, sizeof (char)); if (!ptr->filter) { state = P_MEMERR; break; } if (*sptr == BSLTOK) { if (*(sptr+1) == '\0') { /* error */ state = P_ERROR; break; } if (*(sptr+1) == QUOTETOK || *(sptr+1) == BSLTOK) { /* escaped CHARS */ sptr++; } else { *dptr++ = *sptr++; } *dptr++ = *sptr; } else if (*sptr == QUOTETOK) { quoted = 1; wasquoted = 1; } else { *dptr++ = *sptr; } state = P_FILTER; break; case P_SCOPE: if (*sptr == SEMITOK) { /* no more SSD */ state = P_EXIT; break; } if (strncasecmp(sptr, "base", 4) == 0) { sptr += 4; ptr->scope = NS_LDAP_SCOPE_BASE; } else if (strncasecmp(sptr, "one", 3) == 0) { ptr->scope = NS_LDAP_SCOPE_ONELEVEL; sptr += 3; } else if (strncasecmp(sptr, "sub", 3) == 0) { ptr->scope = NS_LDAP_SCOPE_SUBTREE; sptr += 3; } if (*sptr == '\0' || (*sptr == SEMITOK)) { /* no more SSD */ state = P_EXIT; sptr--; break; } if (*sptr != QUESTTOK) { state = P_ERROR; break; } state = P_INIFILTER; quoted = 0; wasquoted = 0; break; case P_BASEDN: case P_FILTER: if (quoted) { /* Quoted */ if (*sptr == BSLTOK) { if (*(sptr+1) == '\0') { state = P_ERROR; break; } if (*(sptr+1) == QUOTETOK || *(sptr+1) == BSLTOK) { /* escaped CHARS */ sptr++; } else { *dptr++ = *sptr++; } /* fall through to char copy */ } else if (*sptr == QUOTETOK) { /* end of string */ *dptr = '\0'; quoted = 0; break; } /* else fall through to char copy */ } else { /* Unquoted */ if (wasquoted && *sptr != QUESTTOK) { /* error past end of quoted string */ state = P_ERROR; break; } if (*sptr == BSLTOK) { if (*(sptr+1) == '\0') { state = P_ERROR; break; } if (*(sptr+1) == SEMITOK || *(sptr+1) == QUESTTOK || *(sptr+1) == QUOTETOK || *(sptr+1) == BSLTOK) { /* escaped chars */ sptr++; } /* fall through to char copy */ } else if (*sptr == QUOTETOK) { /* error */ state = P_ERROR; break; } else if (*sptr == QUESTTOK) { /* if filter error */ if (state == P_FILTER) { state = P_ERROR; break; } /* end of basedn goto scope */ *dptr = '\0'; state = P_SCOPE; break; } else if (*sptr == SEMITOK) { /* end of current SSD */ *dptr = '\0'; state = P_EXIT; break; } } /* normal character to copy */ *dptr++ = *sptr; break; case P_END: if (*sptr == SEMITOK) { state = P_EXIT; break; } __ns_ldap_freeASearchDesc(ptr); ptr = NULL; *cur = NULL; return (NS_LDAP_CONFIG); default: /* error should never arrive here */ case P_ERROR: __ns_ldap_freeASearchDesc(ptr); ptr = NULL; *cur = NULL; return (NS_LDAP_CONFIG); case P_MEMERR: __ns_ldap_freeASearchDesc(ptr); ptr = NULL; *cur = NULL; return (NS_LDAP_MEMORY); } } if (quoted) { __ns_ldap_freeASearchDesc(ptr); ptr = NULL; *cur = NULL; return (NS_LDAP_INVALID_PARAM); } if (empty || strlen(ptr->basedn) == 0) { if (ptr->basedn) free(ptr->basedn); /* get default base */ rc = __s_api_getDNs(&dns, service, &error); if (rc != NS_LDAP_SUCCESS) { if (dns) { __s_api_free2dArray(dns); dns = NULL; } (void) __ns_ldap_freeError(&error); __ns_ldap_freeASearchDesc(ptr); ptr = NULL; return (NS_LDAP_MEMORY); } ptr->basedn = strdup(dns[0]); __s_api_free2dArray(dns); dns = NULL; } *cur = sptr; *ret = ptr; return (NS_LDAP_SUCCESS); }
int __ns_ldap_getSearchDescriptors( const char *service, ns_ldap_search_desc_t ***desc, ns_ldap_error_t **errorp) { int rc; int slen; void **param = NULL; void **paramVal = NULL; char **sdl, *srv, **sdl_save; char errstr[2 * MAXERROR]; ns_ldap_search_desc_t **sdlist; int cnt, max; int vers; ns_config_t *cfg; ns_ldap_search_desc_t *ret; if ((desc == NULL) || (errorp == NULL)) return (NS_LDAP_INVALID_PARAM); *desc = NULL; *errorp = NULL; rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P, (void ***)¶m, errorp); if (rc != NS_LDAP_SUCCESS) { return (rc); } sdl = (char **)param; cnt = 0; max = 0; sdlist = NULL; cfg = __s_api_get_default_config(); if (cfg == NULL) { (void) snprintf(errstr, sizeof (errstr), gettext("No configuration information available.")); MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr), NULL); return (NS_LDAP_CONFIG); } vers = cfg->version; __s_api_release_config(cfg); /* If using version1 or no sd's process SEARCH_DN if available */ if (vers == NS_LDAP_V1 && param == NULL) { rc = __s_api_get_search_DNs_v1(&sdl, service, errorp); if (rc != NS_LDAP_SUCCESS || sdl == NULL) { return (rc); } sdl_save = sdl; /* Convert a SEARCH_DN to a search descriptor */ for (; *sdl; sdl++) { ret = (ns_ldap_search_desc_t *) calloc(1, sizeof (ns_ldap_search_desc_t)); if (ret == NULL) { (void) __ns_ldap_freeSearchDescriptors(&sdlist); __s_api_free2dArray(sdl_save); return (NS_LDAP_MEMORY); } ret->basedn = strdup(*sdl); if (ret->basedn == NULL) { free(ret); (void) __ns_ldap_freeASearchDesc(ret); (void) __ns_ldap_freeSearchDescriptors(&sdlist); __s_api_free2dArray(sdl_save); return (NS_LDAP_MEMORY); } /* default scope */ if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P, ¶mVal, errorp)) != NS_LDAP_SUCCESS) { (void) __ns_ldap_freeASearchDesc(ret); (void) __ns_ldap_freeSearchDescriptors(&sdlist); __s_api_free2dArray(sdl_save); return (rc); } if (paramVal && *paramVal) ret->scope = * (ScopeType_t *)(*paramVal); else ret->scope = NS_LDAP_SCOPE_ONELEVEL; (void) __ns_ldap_freeParam(¶mVal); paramVal = NULL; rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret); if (rc < 0) { (void) __ns_ldap_freeASearchDesc(ret); (void) __ns_ldap_freeSearchDescriptors(&sdlist); __s_api_free2dArray(sdl_save); return (NS_LDAP_MEMORY); } } __s_api_free2dArray(sdl_save); *desc = sdlist; return (NS_LDAP_SUCCESS); } if (sdl == NULL || service == NULL) { (void) __ns_ldap_freeParam(¶m); param = NULL; *desc = NULL; return (NS_LDAP_SUCCESS); } slen = strlen(service); /* Process the version2 sd's */ for (; *sdl; sdl++) { srv = *sdl; if (strncasecmp(service, srv, slen) != 0) continue; srv += slen; if (*srv != COLONTOK) continue; srv++; while (srv != NULL && *srv != NULL) { /* Process 1 */ rc = __s_api_parseASearchDesc(service, &srv, &ret); if (rc != NS_LDAP_SUCCESS) { (void) __ns_ldap_freeSearchDescriptors(&sdlist); (void) snprintf(errstr, (2 * MAXERROR), gettext( "Invalid serviceSearchDescriptor (%s). " "Illegal configuration"), *sdl); (void) __ns_ldap_freeParam(¶m); param = NULL; MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX, strdup(errstr), NULL); return (rc); } if (ret != NULL) { rc = __ns_ldap_saveSearchDesc( &sdlist, &cnt, &max, ret); } if (rc < 0) { (void) __ns_ldap_freeSearchDescriptors(&sdlist); (void) __ns_ldap_freeParam(¶m); param = NULL; return (NS_LDAP_MEMORY); } } } (void) __ns_ldap_freeParam(¶m); param = NULL; *desc = sdlist; return (NS_LDAP_SUCCESS); }
int main(int argc, char **argv) { extern int optind; char *database = NULL; char *ldapfilter = NULL; char *attribute = "dn"; char **key = NULL; char **ldapattribute = NULL; char *buffer[100]; char *err = NULL; char *p; int index = 1; int c; int rc; int verbose = 0; char *udata = NULL; ns_standalone_conf_t standalone_cfg = standaloneDefaults; ns_ldap_error_t *errorp = NULL; char *authmech = NULL; ns_auth_t auth = {NS_LDAP_AUTH_NONE, NS_LDAP_TLS_NONE, NS_LDAP_SASL_NONE, NS_LDAP_SASLOPT_NONE}; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); openlog("ldaplist", LOG_PID, LOG_USER); if (argc == 2 && strlen(argv[1]) == 2 && strncmp(argv[1], "-h", 2) == 0) { /* preserve backwards compatability, support old -h option */ (void) printMapping(); exit(0); } while ((c = getopt(argc, argv, "h:M:N:P:r:a:D:w:j:dgvl")) != EOF) { switch (c) { case 'd': listflag |= NS_LDAP_SCOPE_BASE; break; case 'g': (void) printMapping(); exit(0); break; /* Never reached */ case 'l': attribute = "NULL"; break; case 'v': verbose = 1; break; case 'M': standalone_cfg.type = NS_LDAP_SERVER; standalone_cfg.SA_DOMAIN = optarg; break; case 'h': standalone_cfg.type = NS_LDAP_SERVER; if (separatePort(optarg, &standalone_cfg.SA_SERVER, &standalone_cfg.SA_PORT) > 0) { exit(1); } break; case 'P': standalone_cfg.type = NS_LDAP_SERVER; standalone_cfg.SA_CERT_PATH = optarg; break; case 'N': standalone_cfg.type = NS_LDAP_SERVER; standalone_cfg.SA_PROFILE_NAME = optarg; break; case 'D': standalone_cfg.type = NS_LDAP_SERVER; standalone_cfg.SA_BIND_DN = strdup(optarg); break; case 'w': if (standalone_cfg.SA_BIND_PWD != NULL) { (void) fprintf(stderr, gettext("The -w option is mutually " "exclusive of -j. -w is ignored.\n")); break; } if (optarg != NULL && optarg[0] == '-' && optarg[1] == '\0') { /* Ask for a password later */ break; } standalone_cfg.type = NS_LDAP_SERVER; standalone_cfg.SA_BIND_PWD = strdup(optarg); break; case 'j': if (standalone_cfg.SA_BIND_PWD != NULL) { (void) fprintf(stderr, gettext("The -w option is mutually " "exclusive of -j. -w is ignored.\n")); free(standalone_cfg.SA_BIND_PWD); } standalone_cfg.type = NS_LDAP_SERVER; standalone_cfg.SA_BIND_PWD = readPwd(optarg); if (standalone_cfg.SA_BIND_PWD == NULL) { exit(1); } break; case 'a': authmech = optarg; break; default: usage(gettext("Invalid option")); } } if (standalone_cfg.type == NS_LDAP_SERVER && standalone_cfg.SA_SERVER == NULL) { (void) fprintf(stderr, gettext("Please specify an LDAP server you want " "to connect to. \n")); exit(1); } if ((c = argc - optind) > 0) database = argv[optind++]; if ((--c) > 0) key = &argv[optind]; if (authmech != NULL) { if (__ns_ldap_initAuth(authmech, &auth, &errorp) != NS_LDAP_SUCCESS) { if (errorp) { (void) fprintf(stderr, "%s", errorp->message); (void) __ns_ldap_freeError(&errorp); } exit(1); } } if (auth.saslmech != NS_LDAP_SASL_GSSAPI && standalone_cfg.SA_BIND_DN != NULL && standalone_cfg.SA_BIND_PWD == NULL) { /* If password is not specified, then prompt user for it. */ standalone_cfg.SA_BIND_PWD = strdup(getpassphrase("Enter password:"******"%s\n", errorp->message); (void) __ns_ldap_freeError(&errorp); } exit(1); } if (authmech != NULL) { if (__ns_ldap_setParam(NS_LDAP_AUTH_P, authmech, &errorp) != NS_LDAP_SUCCESS) { __ns_ldap_cancelStandalone(); if (errorp != NULL) { (void) fprintf(stderr, "%s", errorp->message); (void) __ns_ldap_freeError(&errorp); } exit(1); } } if (standalone_cfg.SA_CRED != NULL) { if (__ns_ldap_setParam(NS_LDAP_CREDENTIAL_LEVEL_P, standalone_cfg.SA_CRED, &errorp) != NS_LDAP_SUCCESS) { __ns_ldap_cancelStandalone(); if (errorp != NULL) { (void) fprintf(stderr, "%s", errorp->message); (void) __ns_ldap_freeError(&errorp); } exit(1); } } if (standalone_cfg.type != NS_CACHEMGR && standalone_cfg.SA_BIND_DN != NULL) { ns_auth_t **authpp = NULL, **authp = NULL; if (__ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp, &errorp) != NS_LDAP_SUCCESS || authpp == NULL) { __ns_ldap_cancelStandalone(); (void) __ns_ldap_freeParam((void ***)&authpp); if (errorp) { (void) fprintf(stderr, gettext(errorp->message)); (void) __ns_ldap_freeError(&errorp); } exit(1); } for (authp = authpp; *authp; authp++) { if ((*authp)->saslmech == NS_LDAP_SASL_GSSAPI) { /* * For now we have no use for bindDN and * bindPassword when using SASL/GSSAPI. */ (void) fprintf(stderr, gettext("Warning: SASL/GSSAPI will be " "used as an authentication method" "The bind DN and password will " "be ignored.\n")); break; } } } /* * If dumpping a database, * or all the containers, * use page control just * in case there are too many entries */ if (!key && !(listflag & NS_LDAP_SCOPE_BASE)) listflag |= NS_LDAP_PAGE_CTRL; /* build the attribute array */ if (strncasecmp(attribute, "NULL", 4) == 0) ldapattribute = NULL; else { buffer[0] = strdup(attribute); while ((p = strchr(attribute, ',')) != NULL) { buffer[index++] = attribute = p + 1; *p = '\0'; } buffer[index] = NULL; ldapattribute = buffer; } /* build the filter */ if (database && (strcasecmp(database, "publickey") == NULL)) { /* user publickey lookup */ char *err1 = NULL; int rc1; rc = rc1 = -1; ldapfilter = set_filter_publickey(key, database, 0, &udata); if (ldapfilter) { if (verbose) { (void) fprintf(stdout, gettext("+++ database=%s\n"), (database ? database : "NULL")); (void) fprintf(stdout, gettext("+++ filter=%s\n"), (ldapfilter ? ldapfilter : "NULL")); (void) fprintf(stdout, gettext("+++ template for merging" "SSD filter=%s\n"), (udata ? udata : "NULL")); } rc = list("passwd", ldapfilter, ldapattribute, &err, udata); free(ldapfilter); free(udata); } /* hosts publickey lookup */ ldapfilter = set_filter_publickey(key, database, 1, &udata); if (ldapfilter) { if (verbose) { (void) fprintf(stdout, gettext("+++ database=%s\n"), (database ? database : "NULL")); (void) fprintf(stdout, gettext("+++ filter=%s\n"), (ldapfilter ? ldapfilter : "NULL")); (void) fprintf(stdout, gettext("+++ template for merging" "SSD filter=%s\n"), (udata ? udata : "NULL")); } rc1 = list("hosts", ldapfilter, ldapattribute, &err1, udata); free(ldapfilter); free(udata); } if (rc == -1 && rc1 == -1) { /* this should never happen */ (void) fprintf(stderr, gettext("ldaplist: invalid publickey lookup\n")); rc = 2; } else if (rc != 0 && rc1 != 0) { (void) fprintf(stderr, gettext("ldaplist: %s\n"), (err ? err : err1)); if (rc == -1) rc = rc1; } else rc = 0; exit(switch_err(rc)); } /* * we set the search filter to (objectclass=*) when we want * to list the directory attribute instead of the entries * (the -d option). */ if (((ldapfilter = set_filter(key, database, &udata)) == NULL) || (listflag == NS_LDAP_SCOPE_BASE)) { ldapfilter = strdup("objectclass=*"); udata = strdup("%s"); } if (verbose) { (void) fprintf(stdout, gettext("+++ database=%s\n"), (database ? database : "NULL")); (void) fprintf(stdout, gettext("+++ filter=%s\n"), (ldapfilter ? ldapfilter : "NULL")); (void) fprintf(stdout, gettext("+++ template for merging SSD filter=%s\n"), (udata ? udata : "NULL")); } if (rc = list(database, ldapfilter, ldapattribute, &err, udata)) (void) fprintf(stderr, gettext("ldaplist: %s\n"), err); __ns_ldap_cancelStandalone(); if (ldapfilter) free(ldapfilter); if (udata) free(udata); exit(switch_err(rc)); return (0); /* Never reached */ }