From owner-p4-projects@FreeBSD.ORG Wed Jul 19 18:57:56 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9262F16A4E0; Wed, 19 Jul 2006 18:57:56 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 57B1316A4DA for ; Wed, 19 Jul 2006 18:57:56 +0000 (UTC) (envelope-from bushman@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id DE40E43D6E for ; Wed, 19 Jul 2006 18:57:54 +0000 (GMT) (envelope-from bushman@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k6JIvsdw076234 for ; Wed, 19 Jul 2006 18:57:54 GMT (envelope-from bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k6JIvsh4076231 for perforce@freebsd.org; Wed, 19 Jul 2006 18:57:54 GMT (envelope-from bushman@freebsd.org) Date: Wed, 19 Jul 2006 18:57:54 GMT Message-Id: <200607191857.k6JIvsh4076231@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bushman@freebsd.org using -f From: Michael Bushkov To: Perforce Change Reviews Cc: Subject: PERFORCE change 101956 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Jul 2006 18:57:57 -0000 http://perforce.freebsd.org/chv.cgi?CH=101956 Change 101956 by bushman@bushman_nss_ldap_cached on 2006/07/19 18:57:27 nss_ldap development in progress Affected files ... .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/Makefile#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.h#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapschema.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#1 add .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldaputil.h#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#2 edit .. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#2 edit Differences ... ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/Makefile#2 (text+ko) ==== @@ -8,7 +8,8 @@ #SHLIB_NAME= nss_ldap.so.${SHLIB_MAJOR} #SHLIBDIR?= /lib -SRCS= nss_ldap.c ldap_passwd.c ldapconn.c ldapschema.c ldaputil.c +SRCS= nss_ldap.c ldap_passwd.c ldapconn.c ldapconf.c ldapschema.c \ + ldapsearch.c ldaputil.c CFLAGS+=-I${.CURDIR}/../libnssutil -I/usr/local/include CFLAGS+=-DINET6 ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.c#2 (text+ko) ==== @@ -29,10 +29,88 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include +#include +#include "ldapconn.h" +#include "ldapschema.h" +#include "ldapconf.h" +#include "ldapsearch.h" #include "ldaputil.h" - + +//static int nss_ldap_parse_passwd(struct nss_ldap_parse_context *, +// struct nss_ldap_search_context *); + + +int +__nss_ldap_parse_passwd(struct nss_ldap_parse_context *pctx, + struct nss_ldap_search_context *sctx) +{ + struct nss_ldap_schema *schema; + struct passwd *pwd; + char *buf; + size_t buflen; + size_t len; + int rv; + + assert(pctx != NULL); + assert(sctx != NULL); + + schema = &sctx->conf->schema; + + rv = __nss_ldap_assign_attr_str(sctx, + _ATM(schema, PASSWD, uid), + &pwd->pw_name, &len, buf, buflen); + if (rv != 0) + goto errfin; + buflen -= len; + buf += len; + + rv = __nss_ldap_assign_attr_uid(sctx, + _AT(schema, uidNumber), + &pwd->pw_uid); + if (rv != 0) + goto errfin; + + rv = __nss_ldap_assign_attr_str(sctx, + _AT(schema, gecos), + &pwd->pw_gecos, &len, buf, buflen); + if (rv != 0) + goto errfin; + buflen -= len; + buf += len; + + rv = __nss_ldap_assign_attr_str(sctx, + _AT(schema, homeDirectory), + &pwd->pw_dir, &len, buf, buflen); + if (rv != 0) + rv = __nss_ldap_assign_str("", &pwd->pw_dir, &len, buf, + buflen); + if (rv != 0) + goto errfin; + buflen -= len; + buf += len; + + + rv = __nss_ldap_assign_attr_str(sctx, + _AT(schema, loginShell), + &pwd->pw_shell, &len, buf, buflen); + if (rv != 0) + rv = __nss_ldap_assign_str("", &pwd->pw_shell, &len, buf, + buflen); + if (rv != 0) + goto errfin; + buflen -= len; + buf += len; + +fin: + return (0); + +errfin: + return (-1); +} + int __ldap_setpwent(void *retval, void *mdata, va_list ap) { ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_passwd.h#2 (text+ko) ==== @@ -26,5 +26,13 @@ * $FreeBSD$ */ +#ifndef _LDAP_PASSWD_H_ +#define _LDAP_PASSWD_H_ + +extern int __nss_ldap_parse_passwd(struct nss_ldap_parse_context *, + struct nss_ldap_search_context *); + extern int __ldap_setpwent(void *, void *, va_list); extern int __ldap_passwd(void *, void *, va_list); + +#endif ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#2 (text+ko) ==== @@ -27,3 +27,304 @@ #include __FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include "ldapschema.h" +#include "ldapconf.h" + +#define NSS_BASE_PREFIX ("nss_base_") +#define NSS_BASE_PREFIX_SIZE (9) + +static int +strbreak(char *str, char **fields, int fields_size) +{ + char *c = str; + int i, num; + + num = 0; + for (i = 0; + ((*fields = + strsep(i < fields_size ? &c : NULL, "\n\t ")) != NULL); + ++i) + if ((*(*fields)) != '\0') { + ++fields; + ++num; + } + + return (num); +} + +static int +get_number(const char *str, int low, int max) +{ + + char *end = NULL; + int res = 0; + + if (str[0] == '\0') + return (-1); + + res = strtol(str, &end, 10); + if (*end != '\0') + return (-1); + else + if (((res >= low) || (low == -1)) && + ((res <= max) || (max == -1))) + return (res); + else + return (-2); +} + +static int +set_base_map(struct nss_ldap_configuration *conf, + char const *left_arg, char const *right_arg) +{ + int rv; + + left_arg = left_arg + NSS_BASE_PREFIX_SIZE; + rv = -1; + + if (strcmp(left_arg, "passwd") == 0) + rv = __nss_ldap_set_schema_filter_base(&conf->schema, + NSS_LDAP_MAP_PASSWD, right_arg); + else if (strcmp(left_arg, "group") == 0) + rv = __nss_ldap_set_schema_filter_base(&conf->schema, + NSS_LDAP_MAP_GROUP, right_arg); + + return (rv); +} + +static int +set_schema_rule(struct nss_ldap_configuration *conf, int rule_id, + char const *arg1, char const *arg2) +{ + struct nss_ldap_schema_rule rule; + struct nss_ldap_rules_collection *rules_coll; + int rv; + + assert(conf != NULL); + assert(arg1 != NULL); + assert(arg2 != NULL); + + rv = __nss_ldap_init_rule(&rule, arg1, arg2); + if (rv != 0) + return (-1); + + rules_coll = __nss_ldap_get_schema_rules(&conf->schema, rule_id); + if (rules_coll == NULL) + return (-1); + + rv = __nss_ldap_add_rule(rules_coll, &rule); + return (rv); +} + +void +__nss_ldap_init_default_config(struct nss_ldap_configuration *conf) +{ + + assert(conf != NULL); + memset(conf, 0, sizeof(struct nss_ldap_configuration)); + + conf->host = strdup("ident2.r61.net ident1.r61.net"); + assert(conf->host != NULL); + + conf->port = LDAP_PORT; + conf->proto_version = NSS_LDAP_PROTO_VERSION_3; + conf->ssl_mode = NSS_LDAP_SSL_START_TLS; + + conf->bind_dn = strdup( + "uid=nssproxy,ou=Users,ou=LDAPAccess,ou=Domains,dc=r61,dc=net"); + assert(conf->bind_dn != NULL); + + conf->root_bind_dn = strdup(conf->bind_dn); + assert(conf->root_bind_dn != NULL); + + conf->bind_pw = strdup("[passwd]"); + assert(conf->bind_pw != NULL); + +// conf->base_passwd = strdup( +// "ou=Users,ou=R61.NET,ou=Domains,dc=r61,dc=net"); +// assert(conf->base_passwd != NULL); +} + +int +__nss_ldap_load_config_from_file(struct nss_ldap_configuration *conf, + char const *fname, struct nss_ldap_config_file_error *err) +{ + FILE *fin; + char buffer[1024]; + char *fields[16]; + int field_count, line_num, value; + int i, res; + + assert(conf != NULL); + assert(fname != NULL); + + printf("fname: %s %d\n", fname, conf->proto_version); + fin = fopen(fname, "r"); + if (fin == NULL) + return (-1); + + res = 0; + line_num = 0; + memset(buffer, 0, sizeof(buffer)); + while ((res == 0) && (fgets(buffer, sizeof(buffer) - 1, fin) != NULL)) { + printf("buffer: %s\n", buffer); + field_count = strbreak(buffer, fields, sizeof(fields)); + ++line_num; + + + if (field_count == 0) + continue; + + switch (fields[0][0]) { + case '#': + case '\0': + printf("== %s, %d ==\n", __FILE__, __LINE__); + continue; + case 'h': + printf("== %s, %d ==\n", __FILE__, __LINE__); + if (strcmp(fields[0], "host") == 0) { + /* TODO: add support for multiple hosts */ + if (field_count >= 2) { + free(conf->host); + conf->host = strdup(fields[1]); + assert(conf->host != NULL); + continue; + } + } + break; + case 'b': + printf("== %s, %d ==\n", __FILE__, __LINE__); + if (strcmp(fields[0], "base") == 0) { + if (field_count == 2) { + free(conf->base); + conf->base = strdup(fields[1]); + assert(conf->base != NULL); + continue; + } + } else if (strcmp(fields[0], "binddn") == 0) { + if (field_count == 2) { + free(conf->bind_dn); + conf->bind_dn = strdup(fields[1]); + assert(conf->bind_dn != NULL); + continue; + } + } else if (strcmp(fields[0], "bindpw") == 0) { + if (field_count == 2) { + free(conf->bind_pw); + conf->bind_pw = strdup(fields[1]); + assert(conf->bind_pw != NULL); + continue; + } + } + break; + case 'l': + printf("== %s, %d ==\n", __FILE__, __LINE__); + /* NOTE: we'd probably better use + * NSS_LDAP_PROTO_VERSION_2 and + * NSS_LDAP_PROTO_VERSION_3 constants here */ + if (strcmp(fields[0], "ldap-version") == 0) { + if ((field_count == 2) && + (value = get_number(fields[1], 2, 3) != -1)) { + conf->proto_version = value; + continue; + } + } + break; + case 'n': + printf("== %s, %d ==\n", __FILE__, __LINE__); + if (strncmp(fields[0], NSS_BASE_PREFIX, + NSS_BASE_PREFIX_SIZE) == 0) { + + if ((field_count == 2) && (set_base_map(conf, + fields[0], fields[1]) != -1)) + continue; + } else if (strcmp(fields[0], "nss_map_attribute") == 0) { + if ((field_count == 3) && + (set_schema_rule(conf, + NSS_LDAP_SCHEMA_MAP_ATTRIBUTE_RULES, + fields[1], + fields[2]) == 0)) + continue; + } else if (strcmp(fields[0], "nss_map_objectclass") == 0) { + if ((field_count == 3) && + (set_schema_rule(conf, + NSS_LDAP_SCHEMA_MAP_OBJECTCLASS_RULES, + fields[1], + fields[2]) == 0)) + continue; + } else if (strcmp(fields[0], "nss_default_attribute_value") == 0) { + if ((field_count == 3) && + (set_schema_rule(conf, + NSS_LDAP_SCHEMA_DEFAULT_VALUE_RULES, + fields[1], + fields[2]) == 0)) + continue; + } else if (strcmp(fields[0], "nss_override_attribute_value") == 0) { + if ((field_count == 3) && + (set_schema_rule(conf, + NSS_LDAP_SCHEMA_OVERRIDE_VALUE_RULES, + fields[1], + fields[2]) == 0)) + continue; + } + break; + case 'p': + printf("== %s, %d ==\n", __FILE__, __LINE__); + if (strcmp(fields[0], "port") == 0) { + if ((field_count == 2) && + (value = get_number(fields[1], 0, -1) != -1)) { + conf->port = value; + continue; + } + } + break; + case 'r': + printf("== %s, %d ==\n", __FILE__, __LINE__); + if (strcmp(fields[0], "rootbinddn") == 0) { + if (field_count == 2) { + free(conf->root_bind_dn); + conf->root_bind_dn = strdup(fields[1]); + assert(conf->root_bind_dn != NULL); + continue; + } + } + break; + case 's': + printf("== %s, %d ==\n", __FILE__, __LINE__); + if (strcmp(fields[0], "ssl") == 0) { + if (field_count == 2) { + if (strcmp(fields[1], "off") == 0) { + conf->ssl_mode = NSS_LDAP_SSL_OFF; + continue; + } else if (strcmp(fields[1], "on") == 0) { + conf->ssl_mode = NSS_LDAP_SSL_ON; + continue; + } else if (strcmp(fields[1], "start_tls") == 0) { + conf->ssl_mode = NSS_LDAP_SSL_START_TLS; + continue; + } + } + } + break; + default: + break; + } + + res = -1; + } + fclose(fin); + + return (res); +} + +void +__nss_ldap_destroy_config(struct nss_ldap_configuration *config) +{ + +} ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#2 (text+ko) ==== @@ -25,3 +25,56 @@ * * $FreeBSD$ */ + +#ifndef _LDAPCONF_H_ +#define _LDAPCONF_H_ + +#define NSS_LDAP_SCOPE_SUB 0 +#define NSS_LDAP_SCOPE_ONE 1 +#define NSS_LDAP_SCOPE_BASE 2 + +#define NSS_LDAP_DEREF_NEVER 0 +#define NSS_LDAP_DEREF_FINDING 1 +#define NSS_LDAP_DEREF_SEARCHING 2 +#define NSS_LDAP_DEREF_ALWAYS 3 + +#define NSS_LDAP_SSL_OFF 0 +#define NSS_LDAP_SSL_ON 1 +#define NSS_LDAP_SSL_START_TLS 2 + +#define NSS_LDAP_SCHEMA_RFC2307 0 +#define NSS_LDAP_SCHEMA_RFC2307BIS 1 + +#define NSS_LDAP_PROTO_VERSION_2 2 +#define NSS_LDAP_PROTO_VERSION_3 3 + +#define NSS_LDAP_MAX_ERR_DESC_SIZE 256 + +struct nss_ldap_configuration +{ + char *host; + int port; + int proto_version; + int ssl_mode; + + char *base; + + char *root_bind_dn; + char *bind_dn; + char *bind_pw; + + struct nss_ldap_schema schema; +}; + +struct nss_ldap_config_file_error +{ + char buffer[NSS_LDAP_MAX_ERR_DESC_SIZE]; + int line; +}; + +void __nss_ldap_init_default_config(struct nss_ldap_configuration *); +int __nss_ldap_load_config_from_file(struct nss_ldap_configuration *, + char const *, struct nss_ldap_config_file_error *); +void __nss_ldap_destroy_config(struct nss_ldap_configuration *); + +#endif /* _LDAPCONF_H_ */ ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.c#2 (text+ko) ==== @@ -28,9 +28,13 @@ #include __FBSDID("$FreeBSD$"); +#include +#include #include #include #include +#include "ldapschema.h" +#include "ldapconf.h" #include "ldaputil.h" #include "ldapconn.h" @@ -40,7 +44,11 @@ struct nss_ldap_connection_error *err) { - return (NULL); + assert(method != NULL); + assert(conf != NULL); + assert(err != NULL); + + return (method->connect_fn(conf, err)); } int @@ -49,7 +57,12 @@ struct nss_ldap_connection_error *err) { - return (0); + assert(method != NULL); + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + return (method->auth_fn(conn, conf, err)); } struct nss_ldap_connection * @@ -58,7 +71,12 @@ struct nss_ldap_connection_error *err) { - return (NULL); + assert(method != NULL); + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + return (method->reconnect_fn(conn, conf, err)); } int @@ -67,7 +85,12 @@ struct nss_ldap_connection_error *err) { - return (0); + assert(method != NULL); + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + return (method->disconnect_fn(conn, conf, err)); } int @@ -76,7 +99,12 @@ struct nss_ldap_connection_error *err) { - return (0); + assert(method != NULL); + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + return (method->prepare_fork_fn(conn, conf, err)); } int @@ -85,7 +113,12 @@ struct nss_ldap_connection_error *err) { - return (0); + assert(method != NULL); + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + return (method->parent_fork_fn(conn, conf, err)); } int @@ -94,7 +127,12 @@ struct nss_ldap_connection_error *err) { - return (0); + assert(method != NULL); + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + return (method->child_fork_fn(conn, conf, err)); } #ifdef NSS_LDAP_SIMPLE_AUTH_ENABLED @@ -102,17 +140,166 @@ __nss_ldap_simple_connect(struct nss_ldap_configuration *conf, struct nss_ldap_connection_error *err) { + struct nss_ldap_connection *conn; + int ldap_version; + int rv; - return (NULL); + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + conn = (struct nss_ldap_connection *)malloc(sizeof( + struct nss_ldap_connection)); + assert(conn != NULL); + memset(conn, 0, sizeof(struct nss_ldap_connection)); + + conn->ld = (LDAP *)ldap_init(conf->host, conf->port); + if (conn->ld == NULL) { + printf("--> %s %d\n", __FILE__, __LINE__); + // TODO: error handling here + free(conn); + return (NULL); + } + + switch (conf->proto_version) { + case NSS_LDAP_PROTO_VERSION_2: + ldap_version = LDAP_VERSION2; + break; + case NSS_LDAP_PROTO_VERSION_3: + ldap_version = LDAP_VERSION3; + break; + default: + // NOT REACHABLE + break; + } + + printf("ldap_version: %d\n", conf->proto_version); + rv = ldap_set_option(conn->ld, LDAP_OPT_PROTOCOL_VERSION, + &ldap_version); + if (rv != LDAP_SUCCESS) { + printf("--> %s %d %d %d %d\n", __FILE__, __LINE__, rv, LDAP_SUCCESS, ldap_version); + ldap_perror(conn->ld, "----->"); + // TODO: error checking + ldap_unbind(conn->ld); + free(conn); + return (NULL); + } + + + return (conn); } - -struct nss_ldap_simple_connection * -__nss_ldap_simple_reconnect(struct nss_ldap_connection *conn, + +int +__nss_ldap_simple_auth(struct nss_ldap_connection *conn, struct nss_ldap_configuration *conf, struct nss_ldap_connection_error *err) -{ +{ + LDAPMessage *res; + int msgid = 0, rc = 0, parse_rc = 0, finished = 0; + char *matched_msg = NULL, *error_msg = NULL; + char **referrals; + LDAPControl **serverctrls; + struct timeval zerotime; + + char *bind_dn; + char *bind_pw; + + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + if (geteuid() != 0) + bind_dn = conf->bind_dn; + else + bind_dn = conf->root_bind_dn; + + /* TODO: maybe we should have root_bind_pw? */ + bind_pw = conf->bind_pw; + + printf("bind_dn: %s, bind_pw: %s\n", bind_dn, bind_pw); + - return (NULL); + /* Send an LDAP bind request to the server. */ + msgid = ldap_simple_bind(conn->ld, bind_dn, bind_pw); + + /* If the returned message ID is less than zero, an error occurred. */ + if ( msgid < 0 ) { + /* NOTE: can't use ldap_result2error here */ + err->err_num = msgid; + strlcpy(err->description, ldap_err2string(rc), + sizeof(err->description)); + return (-1); + } + + /* Check to see if the bind operation completed. */ + while ( !finished ) { + rc = ldap_result( conn->ld, msgid, 0, &zerotime, &res ); + switch ( rc ) { + /* If ldap_result() returns -1, error occurred. */ + case -1: + err->err_num = ldap_result2error(conn->ld, res, 0); + strlcpy(err->description, ldap_err2string(rc), + sizeof(err->description)); + return (-1); + + /* If ldap_result() returns 0, the timeout (specified by the + timeout argument) has been exceeded before the client received + the results from the server. Continue calling ldap_result() + to poll for results from the server. */ + case 0: + break; + + default: + /* The client has received the result of the bind operation. */ + finished = 1; + + /* Parse this result to determine if the operation was successful. + Note that a non-zero value is passed as the last parameter, + which indicates that the LDAPMessage structure res should be + freed when done. (No need to call ldap_msgfree().) */ + parse_rc = ldap_parse_result( conn->ld, res, &rc, + &matched_msg, &error_msg, &referrals, + &serverctrls, 1 ); + if ( parse_rc != LDAP_SUCCESS ) { + err->err_num = parse_rc; + strlcpy(err->description, ldap_err2string(rc), + sizeof(err->description)); + return (-1); + } + + /* Check the results of the operation. */ + if ( rc != LDAP_SUCCESS ) { + err->err_num = rc; + strlcpy(err->description, ldap_err2string(rc), + sizeof(err->description)); + + /* If the server sent an additional error message, + print it out. */ + if ( error_msg != NULL && *error_msg != '\0' ) { + strlcat(err->description, ", ", + sizeof(err->description)); + strlcat(err->description, error_msg, + sizeof(err->description)); + } + + /* If an entry specified by a DN could not be found, + the server may also return the portion of the DN + that identifies an existing entry. + (See"Receiving the Portion of the DN Matching an Entry" + for an explanation.) */ + if ( matched_msg != NULL && *matched_msg != '\0' ) { + strlcat(err->description, + ", matched part:", + sizeof(err->description)); + strlcat(err->description, matched_msg, + sizeof(err->description)); + } + return (-1); + } else + return (0); + break; + } + } } int @@ -121,7 +308,19 @@ struct nss_ldap_connection_error *err) { - return (NULL); + int rv; + + assert(conn != NULL); + assert(conf != NULL); + assert(err != NULL); + + rv = ldap_unbind(conn->ld); + if (rv != LDAP_SUCCESS) { + //TODO: error checking + return (-1); + } + + return (0); } int @@ -132,7 +331,7 @@ memset(method, 0, sizeof(struct nss_ldap_connection_method)); method->connect_fn = __nss_ldap_simple_connect; - method->reconnect_fn = __nss_ldap_simple_reconnect; + method->auth_fn = __nss_ldap_simple_auth; method->disconnect_fn = __nss_ldap_simple_disconnect; return (0); @@ -153,73 +352,36 @@ __nss_ldap_start_tls_connect(struct nss_ldap_configuration *conf, struct nss_ldap_connection_error *err) { - struct nss_ldap_start_tls_connection *conn; - int rv, int msgid; + struct nss_ldap_connection *conn; + int rv; - assert(conf != NULL); - assert(err != NULL); - - conn = (struct nss_ldap_start_tls_connection *)malloc( - sizeof(struct nss_ldap_start_tls_connection)); - assert(conn != NULL); - memset(conn, 0, sizeof(struct nss_ldap_start_tls_connection)); - conn->conn_type = NSS_LDAP_CONNECTION_START_TLS; - - conn->ld = ldap_init(conf->host, conf->port); - if (conn->ld == NULL) { - /* TODO: error checking */ - free(conn); + conn = __nss_ldap_simple_connect(conf, err); + if (conn == NULL) return (NULL); - } - rv = ldap_start_tls(conn->ld, NULL, NULL); + rv = ldap_start_tls_s(conn->ld, NULL, NULL); if (rv != LDAP_SUCCESS) { /* TODO: error checking */ - ldap_unbind(conn->ld); - free(conn); + __nss_ldap_simple_disconnect(conn, conf, err); return (NULL); } - rv = ldap_bind( - - return ((struct nss_ldap_connection *)conn); + return (conn); } -struct nss_ldap_connection * -__nss_ldap_start_tls_reconnect(struct nss_ldap_connection *conn, - struct nss_ldap_configuration *conf, - struct nss_ldap_connection_error *err) +int +__nss_ldap_init_start_tls_simple_auth_method( + struct nss_ldap_connection_method *method) { - - /* TODO: implement */ - return (NULL); -} - -int -__nss_ldap_start_tls_disconnect(struct nss_ldap_connection *conn, - struct nss_ldap_configuration *conf, - struct nss_ldap_connection_error *err) -{ int rv; + assert(method != NULL); - assert(conn != NULL); - assert(conf != NULL); - assert(err != NULL); + rv = __nss_ldap_init_simple_auth_method(method); + if (rv != 0) + return (rv); - rv = ldap_unbind(conn->ld); - if (rv != LDAP_SUCCESS) { - /* TODO: error checking code */ - rv = -1; - } else - rv = 0; - - free(conn); - return (rv); -} - -int -__nss_ldap_start_tls_auth_method(struct nss_ldap_connection_method *method) -{ + /* Replacing standard connect routine with start-tls specific */ + method->connect_fn = __nss_ldap_start_tls_connect; return (0); } ==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconn.h#2 (text+ko) ==== @@ -26,9 +26,16 @@ * $FreeBSD$ */ +#ifndef _LDAPCONN_H_ +#define _LDAPCONN_H_ + +/* TODO: remove in release */ +#define NSS_LDAP_START_TLS_AUTH_ENABLED +#define NSS_LDAP_SIMPLE_AUTH_ENABLED + #define NSS_LDAP_MAX_ERR_DESC_SIZE 256 /* TODO: is this correct? */ -#define NSS_LDAP_SOCK_NAME_SIZE (sizeof(struct sockaddr)) +#define NSS_LDAP_SOCK_NAME_SIZE 32 #define NSS_LDAP_CONNECTION_SIMPLE 0 #define NSS_LDAP_CONNECTION_SSL 1 @@ -40,6 +47,8 @@ char sockname[NSS_LDAP_SOCK_NAME_SIZE]; char peername[NSS_LDAP_SOCK_NAME_SIZE]; + + void *mdata; }; struct nss_ldap_connection_error @@ -48,6 +57,8 @@ int err_num; }; +struct nss_ldap_configuration; + typedef struct nss_ldap_connection *(*nss_ldap_conn_fn)( struct nss_ldap_configuration *, struct nss_ldap_connection_error *); @@ -77,11 +88,10 @@ struct nss_ldap_connection_method *, struct nss_ldap_configuration *, struct nss_ldap_connection_error *); extern int __nss_ldap_auth(struct nss_ldap_connection_method *, - struct nss_ldap_connection *, struct nss_ldap_configuration, + struct nss_ldap_connection *, struct nss_ldap_configuration *, struct nss_ldap_connection_error *); extern struct nss_ldap_connection *__nss_ldap_reconnect( - struct nss_ldap_connection_method *, - struct nss_ldap_connection *, + struct nss_ldap_connection_method *, struct nss_ldap_connection *, struct nss_ldap_configuration *, struct nss_ldap_connection_error *); extern int __nss_ldap_disconnect( @@ -101,13 +111,9 @@ struct nss_ldap_connection_error *); #ifdef NSS_LDAP_SIMPLE_AUTH_ENABLED -/* TODO: this is a bit dirty */ -#define nss_ldap_connection nss_ldap_simple_connection - extern struct nss_ldap_connection *__nss_ldap_simple_connect( struct nss_ldap_configuration *, struct nss_ldap_connection_error *); -extern struct nss_ldap_simple_connection *__nss_ldap_simple_reconnect( - struct nss_ldap_connection *, +extern int __nss_ldap_simple_auth(struct nss_ldap_connection *, struct nss_ldap_configuration *, struct nss_ldap_connection_error *); extern int __nss_ldap_simple_disconnect(struct nss_ldap_connection *, struct nss_ldap_configuration *, @@ -118,22 +124,14 @@ #endif #ifdef NSS_LDAP_SSL_AUTH_ENABLED -extern int __nss_ldap_init_ssl_auth_method( - struct nss_ldap_connection_method *); #endif #if defined(NSS_LDAP_START_TLS_AUTH_ENABLED) && defined(NSS_LDAP_SIMPLE_AUTH_ENABLED) >>> TRUNCATED FOR MAIL (1000 lines) <<<