Пример #1
0
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,
	    &paramVal, 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(&paramVal);
	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);
}
Пример #2
0
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 ***)&param, 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,
			    &paramVal, 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(&paramVal);
			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(&param);
		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(&param);
				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(&param);
				param = NULL;
				return (NS_LDAP_MEMORY);
			}
		}
	}

	(void) __ns_ldap_freeParam(&param);
	param = NULL;
	*desc = sdlist;
	return (NS_LDAP_SUCCESS);
}
Пример #3
0
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 */
}