From db14b113e055fa7ab006cfe1c04961bba19a85de Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Sat, 11 Nov 2006 14:02:25 +0000 Subject: simplify some functions to pass file pointer around instead of struct and buffer (initially only for alias_byname()) git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@84 ef36b2f9-881f-0410-afb5-c4e39611909c --- server/aliases.c | 38 +++++++++--------- server/ldap-nss.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ server/ldap-nss.h | 12 ++++++ server/util.c | 72 +++++++++++++++++++++++++++++++++ server/util.h | 4 +- 5 files changed, 224 insertions(+), 19 deletions(-) (limited to 'server') diff --git a/server/aliases.c b/server/aliases.c index 248ddc8..d7031fd 100644 --- a/server/aliases.c +++ b/server/aliases.c @@ -42,8 +42,6 @@ #include "common.h" #include "log.h" -static struct ent_context *alias_context = NULL; - static enum nss_status _nss_ldap_parse_alias( LDAPMessage *e,struct ldap_state *pvt,void *result, char *buffer,size_t buflen) @@ -61,6 +59,19 @@ static enum nss_status _nss_ldap_parse_alias( return stat; } +static int write_alias(LDAPMessage *e,struct ldap_state *pvt,FILE *fp) +{ + int stat; + log_log(LOG_DEBUG,"write_alias: _nss_ldap_write_rndvalue"); + if ((stat=_nss_ldap_write_rndvalue(fp,e,ATM(LM_ALIASES,cn)))!=NSLCD_RESULT_SUCCESS) + return stat; + log_log(LOG_DEBUG,"write_alias: _nss_ldap_write_attrvals"); + if ((stat=_nss_ldap_write_attrvals(fp,e,AT(rfc822MailMember)))!=NSLCD_RESULT_SUCCESS) + return stat; + return NSLCD_RESULT_SUCCESS; +} + + /* macros for expanding the LDF_ALIAS macro */ #define LDF_STRING(field) WRITE_STRING(fp,field) #define LDF_STRINGLIST(field) WRITE_STRINGLIST_NUM(fp,field,result.alias_members_len) @@ -69,33 +80,23 @@ static enum nss_status _nss_ldap_parse_alias( int nslcd_alias_byname(FILE *fp) { - int32_t tmpint32,tmp2int32; + int32_t tmpint32; char *name; - /* these are here for now until we rewrite the LDAP code */ - struct aliasent result; - char buffer[1024]; - int errnop; - int retv; struct ldap_args a; /* read request parameters */ READ_STRING_ALLOC(fp,name); /* log call */ log_log(LOG_DEBUG,"nslcd_alias_byname(%s)",name); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_ALIAS_BYNAME); /* do the LDAP request */ LA_INIT(a); LA_STRING(a)=name; LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getaliasbyname,LM_ALIASES,_nss_ldap_parse_alias)); + _nss_ldap_searchbyname(&a,_nss_ldap_filt_getaliasbyname,LM_ALIASES,fp,write_alias); /* no more need for this */ free(name); - /* write the response */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_ALIAS_BYNAME); - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - LDF_ALIAS; - } WRITE_FLUSH(fp); log_log(LOG_DEBUG,"nslcd_alias_byname DONE"); /* we're done */ @@ -105,6 +106,7 @@ int nslcd_alias_byname(FILE *fp) int nslcd_alias_all(FILE *fp) { int32_t tmpint32,tmp2int32; + static struct ent_context *alias_context; /* these are here for now until we rewrite the LDAP code */ struct aliasent result; char buffer[1024]; @@ -123,7 +125,7 @@ int nslcd_alias_all(FILE *fp) { /* write the result code */ WRITE_INT32(fp,retv); - /* write the password entry */ + /* write the alias entry */ LDF_ALIAS; fflush(fp); } diff --git a/server/ldap-nss.c b/server/ldap-nss.c index f5d4539..73b5a29 100644 --- a/server/ldap-nss.c +++ b/server/ldap-nss.c @@ -84,6 +84,9 @@ #include "util.h" #include "dnsconfig.h" #include "pagectrl.h" +#include "nslcd-server.h" +#include "common.h" +#include "log.h" #if defined(HAVE_THREAD_H) #ifdef HAVE_PTHREAD_ATFORK @@ -3207,6 +3210,94 @@ _nss_ldap_getbyname (struct ldap_args * args, return stat; } +static int NEW_do_parse_s(struct ent_context *ctx,FILE *fp,NEWparser_t parser) +{ + int parseStat=NSLCD_RESULT_NOTFOUND; + LDAPMessage *e=NULL; + /* + * if ec_state.ls_info.ls_index is non-zero, then we don't collect another + * entry off the LDAP chain, and instead refeed the existing result to + * the parser. Once the parser has finished with it, it will return + * NSS_STATUS_NOTFOUND and reset the index to -1, at which point we'll retrieve + * another entry. + */ + do + { + if (ctx->ec_state.ls_retry == 0 && + (ctx->ec_state.ls_type == LS_TYPE_KEY + || ctx->ec_state.ls_info.ls_index == -1)) + { + if (e == NULL) + e = ldap_first_entry (__session.ls_conn, ctx->ec_res); + else + e = ldap_next_entry (__session.ls_conn, e); + } + if (e == NULL) + { + /* Could not get a result; bail */ + parseStat=NSLCD_RESULT_NOTFOUND; + break; + } + /* + * We have an entry; now, try to parse it. + * + * If we do not parse the entry because of a schema + * violation, the parser should return NSS_STATUS_NOTFOUND. + * We'll keep on trying subsequent entries until we + * find one which is parseable, or exhaust avialable + * entries, whichever is first. + */ + parseStat=parser(e,&ctx->ec_state,fp); + /* hold onto the state if we're out of memory XXX */ + ctx->ec_state.ls_retry=0; + } + while (parseStat==NSLCD_RESULT_NOTFOUND); + return parseStat; +} + + +int _nss_ldap_searchbyname( + struct ldap_args *args,const char *filterprot, + enum ldap_map_selector sel,FILE *fp,NEWparser_t parser) +{ + int stat; + struct ent_context ctx; + int32_t tmpint32; + + _nss_ldap_enter(); + + ctx.ec_msgid=-1; + ctx.ec_cookie=NULL; + + stat=nss2nslcd(_nss_ldap_search_s(args,filterprot,sel,NULL,1,&ctx.ec_res)); + /* write the result code */ + WRITE_INT32(fp,stat); + /* bail on nothing found */ + if (stat!=NSLCD_RESULT_SUCCESS) + { + _nss_ldap_leave(); + return 1; + } + /* + * we pass this along for the benefit of the services parser, + * which uses it to figure out which protocol we really wanted. + * we only pass the second argument along, as that's what we need + * in services. + */ + LS_INIT(ctx.ec_state); + ctx.ec_state.ls_type=LS_TYPE_KEY; + ctx.ec_state.ls_info.ls_key=args->la_arg2.la_string; + /* call the parser for the result */ + stat=NEW_do_parse_s(&ctx,fp,parser); + + _nss_ldap_ent_context_release(&ctx); + + /* moved unlock here to avoid race condition bug #49 */ + _nss_ldap_leave(); + + return stat; +} + /* * These functions are called from within the parser, where it is assumed * to be safe to use the connection and the respective message. @@ -3308,6 +3399,32 @@ _nss_ldap_assign_attrvals (LDAPMessage * e, return NSS_STATUS_SUCCESS; } +int _nss_ldap_write_attrvals(FILE *fp,LDAPMessage *e,const char *attr) +{ + char **vals; + int valcount; + int i; + int32_t tmpint32; + /* log */ + log_log(LOG_DEBUG,"_nss_ldap_write_attrvals(%s)",attr); + /* check if we have a connection */ + if (__session.ls_conn==NULL) + return NSLCD_RESULT_UNAVAIL; + /* get the values and the number of values */ + vals=ldap_get_values(__session.ls_conn,e,(char *)attr); + valcount=(vals==NULL)?0:ldap_count_values(vals); + /* write number of entries */ + WRITE_INT32(fp,valcount); + /* write the entries themselves */ + for (i=0;i