diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2007-09-07 22:51:46 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2007-09-07 22:51:46 +0200 |
commit | 30423d96ecd243663906a3a1c13f1f0e90ac6330 (patch) | |
tree | ed94021c35b761bc355e7bec8cf4ce4379fe9c86 /nslcd/ldap-nss.c | |
parent | 6592036689c38566acbafc178e1f22098279263f (diff) |
make handling of ent_context consistent and simpler
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@382 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nslcd/ldap-nss.c')
-rw-r--r-- | nslcd/ldap-nss.c | 326 |
1 files changed, 120 insertions, 206 deletions
diff --git a/nslcd/ldap-nss.c b/nslcd/ldap-nss.c index 3a36010..b9b05ec 100644 --- a/nslcd/ldap-nss.c +++ b/nslcd/ldap-nss.c @@ -666,7 +666,6 @@ do_init_session (LDAP ** ld, const char *uri) { int rc; int ldaps; - char uribuf[1024]; char *p; enum nss_status stat; @@ -1137,32 +1136,11 @@ do_open (void) } /* - * This function initializes an enumeration context, acquiring - * the global mutex. - * - * It could be done from the default constructor, under Solaris, but we - * delay it until the setXXent() function is called. - */ -struct ent_context * -_nss_ldap_ent_context_init (struct ent_context ** pctx) -{ - struct ent_context *ctx; - - _nss_ldap_enter (); - - ctx = _nss_ldap_ent_context_init_locked (pctx); - - _nss_ldap_leave (); - - return ctx; -} - -/* * Wrapper around ldap_result() to skip over search references * and deal transparently with the last entry. */ static enum nss_status -do_result (struct ent_context * ctx, int all) +do_result (struct ent_context *context, int all) { int rc = LDAP_UNAVAILABLE; enum nss_status stat = NSS_STATUS_TRYAGAIN; @@ -1183,15 +1161,15 @@ do_result (struct ent_context * ctx, int all) do { - if (ctx->ec_res != NULL) - { - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; - } + if (context->ec_res!=NULL) + { + ldap_msgfree(context->ec_res); + context->ec_res=NULL; + } rc = - ldap_result (__session.ls_conn, ctx->ec_msgid, all, tvp, - &ctx->ec_res); + ldap_result (__session.ls_conn, context->ec_msgid, all, tvp, + &(context->ec_res)); switch (rc) { case -1: @@ -1218,19 +1196,19 @@ do_result (struct ent_context * ctx, int all) { #ifdef LDAP_MORE_RESULTS_TO_RETURN int parserc; - /* NB: this frees ctx->ec_res */ + /* NB: this frees context->ec_res */ LDAPControl **resultControls = NULL; - ctx->ec_cookie = NULL; + context->ec_cookie = NULL; parserc = - ldap_parse_result (__session.ls_conn, ctx->ec_res, &rc, NULL, + ldap_parse_result (__session.ls_conn, context->ec_res, &rc, NULL, NULL, NULL, &resultControls, 1); if (parserc != LDAP_SUCCESS && parserc != LDAP_MORE_RESULTS_TO_RETURN) { stat = NSS_STATUS_UNAVAIL; - ldap_abandon (__session.ls_conn, ctx->ec_msgid); + ldap_abandon (__session.ls_conn, context->ec_msgid); log_log(LOG_ERR,"could not get LDAP result - %s", ldap_err2string (rc)); } @@ -1239,7 +1217,7 @@ do_result (struct ent_context * ctx, int all) /* See if there are any more pages to come */ parserc = ldap_parse_page_control (__session.ls_conn, resultControls, NULL, - &(ctx->ec_cookie)); + &(context->ec_cookie)); ldap_controls_free (resultControls); stat = NSS_STATUS_NOTFOUND; } @@ -1250,8 +1228,8 @@ do_result (struct ent_context * ctx, int all) #else stat = NSS_STATUS_NOTFOUND; #endif /* LDAP_MORE_RESULTS_TO_RETURN */ - ctx->ec_res = NULL; - ctx->ec_msgid = -1; + context->ec_res = NULL; + context->ec_msgid = -1; } break; default: @@ -1274,106 +1252,65 @@ do_result (struct ent_context * ctx, int all) } /* - * This function initializes an enumeration context. + * This function initializes an enumeration context, acquiring + * the global mutex. * * It could be done from the default constructor, under Solaris, but we * delay it until the setXXent() function is called. */ -struct ent_context * -_nss_ldap_ent_context_init_locked(struct ent_context **pctx) +void _nss_ldap_ent_context_init(struct ent_context *context) { - struct ent_context *ctx; - - log_log(LOG_DEBUG,"==> _nss_ldap_ent_context_init_locked"); - - ctx = *pctx; - - if (ctx == NULL) - { - ctx=(struct ent_context *)malloc(sizeof(struct ent_context)); - if (ctx == NULL) - { - log_log(LOG_DEBUG,"<== _nss_ldap_ent_context_init_locked"); - return NULL; - } - *pctx = ctx; - } - else - { - if (ctx->ec_res != NULL) - { - ldap_msgfree (ctx->ec_res); - } - if (ctx->ec_cookie != NULL) - { - ber_bvfree (ctx->ec_cookie); - } - if (ctx->ec_msgid > -1 && do_result (ctx, LDAP_MSG_ONE) == NSS_STATUS_SUCCESS) - { - ldap_abandon (__session.ls_conn, ctx->ec_msgid); - } - } - - ctx->ec_cookie = NULL; - ctx->ec_res = NULL; - ctx->ec_msgid = -1; - ctx->ec_sd = NULL; - - LS_INIT (ctx->ec_state); - - log_log(LOG_DEBUG,"<== _nss_ldap_ent_context_init_locked"); + _nss_ldap_enter(); + _nss_ldap_ent_context_init_locked(context); + _nss_ldap_leave(); +} - return ctx; +/* + * This function initializes an enumeration context. + * + * It could be done from the default constructor, under Solaris, but we + * delay it until the setXXent() function is called. + */ +void _nss_ldap_ent_context_init_locked(struct ent_context *context) +{ + /* TODO: find out why we need to have aquired a lock for this */ + context->ec_cookie=NULL; + context->ec_res=NULL; + context->ec_msgid=-1; + context->ec_sd=NULL; + LS_INIT(context->ec_state); } /* * Clears a given context; we require the caller * to acquire the lock. */ -void -_nss_ldap_ent_context_release (struct ent_context * ctx) +void _nss_ldap_ent_context_cleanup(struct ent_context *context) { - log_log(LOG_DEBUG,"==> _nss_ldap_ent_context_release"); - - if (ctx == NULL) - { - log_log(LOG_DEBUG,"<== _nss_ldap_ent_context_release"); - return; - } - - if (ctx->ec_res != NULL) - { - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; - } - - /* - * Abandon the search if there were more results to fetch. - */ - if (ctx->ec_msgid > -1 && do_result (ctx, LDAP_MSG_ONE) == NSS_STATUS_SUCCESS) - { - ldap_abandon (__session.ls_conn, ctx->ec_msgid); - ctx->ec_msgid = -1; - } - - if (ctx->ec_cookie != NULL) - { - ber_bvfree (ctx->ec_cookie); - ctx->ec_cookie = NULL; - } - - ctx->ec_sd = NULL; - - LS_INIT (ctx->ec_state); - - if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT)) - { - do_close (); - } - - log_log(LOG_DEBUG,"<== _nss_ldap_ent_context_release"); - - return; + if (context==NULL) + return; + /* free read messages */ + if (context->ec_res!=NULL) + { + ldap_msgfree(context->ec_res); + context->ec_res=NULL; + } + /* abandon the search if there were more results to fetch */ + if ((context->ec_msgid>-1)&&(do_result(context,LDAP_MSG_ONE)==NSS_STATUS_SUCCESS)) + { + ldap_abandon(__session.ls_conn,context->ec_msgid); + context->ec_msgid=-1; + } + /* clean up cookie */ + if (context->ec_cookie!=NULL) + { + ber_bvfree(context->ec_cookie); + context->ec_cookie=NULL; + } + context->ec_sd=NULL; + LS_INIT(context->ec_state); + if (_nss_ldap_test_config_flag(NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT)) + do_close (); } /* @@ -1624,7 +1561,7 @@ do_map_errno (enum nss_status status, int *errnop) * correctly or there is an exceptional condition. */ static enum nss_status -do_parse (struct ent_context * ctx, void *result, char +do_parse (struct ent_context *context, void *result, char *buffer, size_t buflen, int *errnop, parser_t parser) { enum nss_status parseStat = NSS_STATUS_NOTFOUND; @@ -1642,11 +1579,11 @@ do_parse (struct ent_context * ctx, void *result, char { enum nss_status resultStat = NSS_STATUS_SUCCESS; - if (ctx->ec_state.ls_retry == 0 && - (ctx->ec_state.ls_type == LS_TYPE_KEY - || ctx->ec_state.ls_info.ls_index == -1)) + if ((context->ec_state.ls_retry==0) && + ( (context->ec_state.ls_type==LS_TYPE_KEY) || + (context->ec_state.ls_info.ls_index==-1) )) { - resultStat = do_result (ctx, LDAP_MSG_ONE); + resultStat=do_result(context,LDAP_MSG_ONE); } if (resultStat != NSS_STATUS_SUCCESS) @@ -1665,20 +1602,19 @@ do_parse (struct ent_context * ctx, void *result, char * find one which is parseable, or exhaust avialable * entries, whichever is first. */ - parseStat = parser (ctx->ec_res, &ctx->ec_state, result, - buffer, buflen); + parseStat=parser(context->ec_res,&(context->ec_state),result,buffer,buflen); /* hold onto the state if we're out of memory XXX */ - ctx->ec_state.ls_retry = (parseStat == NSS_STATUS_TRYAGAIN && buffer != NULL ? 1 : 0); + context->ec_state.ls_retry = (parseStat == NSS_STATUS_TRYAGAIN && buffer != NULL ? 1 : 0); /* free entry is we're moving on */ - if (ctx->ec_state.ls_retry == 0 && - (ctx->ec_state.ls_type == LS_TYPE_KEY - || ctx->ec_state.ls_info.ls_index == -1)) + if ((context->ec_state.ls_retry==0) && + ( (context->ec_state.ls_type==LS_TYPE_KEY) || + (context->ec_state.ls_info.ls_index==-1) )) { /* we don't need the result anymore, ditch it. */ - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; + ldap_msgfree(context->ec_res); + context->ec_res=NULL; } } while (parseStat == NSS_STATUS_NOTFOUND); @@ -1694,7 +1630,7 @@ do_parse (struct ent_context * ctx, void *result, char * Parse, fetching reuslts from chain instead of server. */ static enum nss_status -do_parse_s (struct ent_context * ctx, void *result, char +do_parse_s (struct ent_context *context, void *result, char *buffer, size_t buflen, int *errnop, parser_t parser) { enum nss_status parseStat = NSS_STATUS_NOTFOUND; @@ -1711,12 +1647,12 @@ do_parse_s (struct ent_context * ctx, void *result, char */ 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 ((context->ec_state.ls_retry==0) && + ( (context->ec_state.ls_type==LS_TYPE_KEY) || + (context->ec_state.ls_info.ls_index==-1) )) { if (e == NULL) - e = ldap_first_entry (__session.ls_conn, ctx->ec_res); + e = ldap_first_entry (__session.ls_conn, context->ec_res); else e = ldap_next_entry (__session.ls_conn, e); } @@ -1737,10 +1673,10 @@ do_parse_s (struct ent_context * ctx, void *result, char * find one which is parseable, or exhaust avialable * entries, whichever is first. */ - parseStat = parser (e, &ctx->ec_state, result, buffer, buflen); + parseStat=parser(e,&(context->ec_state),result,buffer,buflen); /* hold onto the state if we're out of memory XXX */ - ctx->ec_state.ls_retry = (parseStat == NSS_STATUS_TRYAGAIN && buffer != NULL ? 1 : 0); + context->ec_state.ls_retry=(parseStat==NSS_STATUS_TRYAGAIN)&&(buffer!=NULL); } while (parseStat == NSS_STATUS_NOTFOUND); @@ -2015,7 +1951,7 @@ do_next_page (const char *base,const char *filter,const char **attrs, * Locks mutex. */ int -_nss_ldap_getent(struct ent_context **ctx, +_nss_ldap_getent(struct ent_context *context, void *result,char *buffer,size_t buflen,int *errnop, const char *base,const char *filter, const char **attrs, enum ldap_map_selector sel, parser_t parser) @@ -2027,7 +1963,7 @@ _nss_ldap_getent(struct ent_context **ctx, * of the context. */ _nss_ldap_enter(); - status=nss2nslcd(_nss_ldap_getent_ex(ctx,result, + status=nss2nslcd(_nss_ldap_getent_locked(context,result, buffer,buflen, errnop,base,filter,attrs,sel,parser)); _nss_ldap_leave(); @@ -2039,73 +1975,53 @@ _nss_ldap_getent(struct ent_context **ctx, * Caller holds global mutex */ enum nss_status -_nss_ldap_getent_ex(struct ent_context **ctx, +_nss_ldap_getent_locked(struct ent_context *context, void *result,char *buffer,size_t buflen,int *errnop, const char *base,const char *filter, const char **attrs, enum ldap_map_selector sel,parser_t parser) { enum nss_status stat = NSS_STATUS_SUCCESS; - - log_log(LOG_DEBUG,"==> _nss_ldap_getent_ex (base=\"%s\", filter=\"%s\")",base,filter); - - if (*ctx == NULL || (*ctx)->ec_msgid < 0) - { - /* - * implicitly call setent() if this is the first time - * or there is no active search - */ - if (_nss_ldap_ent_context_init_locked (ctx) == NULL) - { - log_log(LOG_DEBUG,"<== _nss_ldap_getent_ex"); - return NSS_STATUS_UNAVAIL; - } - } - + int msgid; + log_log(LOG_DEBUG,"==> _nss_ldap_getent_locked (base=\"%s\", filter=\"%s\")",base,filter); next: - /* - * If ctx->ec_msgid < 0, then we haven't searched yet. Let's do it! - */ - if ((*ctx)->ec_msgid < 0) + /* if context->ec_msgid < 0, then we haven't searched yet */ + if (context->ec_msgid<0) { - int msgid; - stat=_nss_ldap_search(base,filter,attrs,sel, - LDAP_NO_LIMIT,&msgid,&(*ctx)->ec_sd); + LDAP_NO_LIMIT,&msgid,&(context->ec_sd)); if (stat != NSS_STATUS_SUCCESS) { - log_log(LOG_DEBUG,"<== _nss_ldap_getent_ex"); + log_log(LOG_DEBUG,"<== _nss_ldap_getent_locked"); return stat; } - - (*ctx)->ec_msgid = msgid; + context->ec_msgid=msgid; } - stat = do_parse(*ctx, result, buffer, buflen, errnop, parser); + stat=do_parse(context,result,buffer,buflen,errnop,parser); - if (stat == NSS_STATUS_NOTFOUND) + if (stat==NSS_STATUS_NOTFOUND) { /* Is there another page of results? */ - if ((*ctx)->ec_cookie != NULL && (*ctx)->ec_cookie->bv_len != 0) + if ((context->ec_cookie!=NULL)&&(context->ec_cookie->bv_len!=0)) { - int msgid; stat=do_next_page(base,filter,attrs,sel,LDAP_NO_LIMIT,&msgid, - (*ctx)->ec_cookie); + context->ec_cookie); if (stat!=NSS_STATUS_SUCCESS) { - log_log(LOG_DEBUG,"<== _nss_ldap_getent_ex"); + log_log(LOG_DEBUG,"<== _nss_ldap_getent_locked"); return stat; } - (*ctx)->ec_msgid=msgid; - stat=do_parse(*ctx,result,buffer,buflen,errnop,parser); + context->ec_msgid=msgid; + stat=do_parse(context,result,buffer,buflen,errnop,parser); } } - if (stat == NSS_STATUS_NOTFOUND && (*ctx)->ec_sd != NULL) + if ((stat==NSS_STATUS_NOTFOUND)&&(context->ec_sd!=NULL)) { - (*ctx)->ec_msgid = -1; + context->ec_msgid = -1; goto next; } - log_log(LOG_DEBUG,"<== _nss_ldap_getent_ex"); + log_log(LOG_DEBUG,"<== _nss_ldap_getent_locked"); return stat; } @@ -2121,16 +2037,15 @@ int _nss_ldap_getbyname(void *result, char *buffer, size_t buflen, { enum nss_status stat = NSS_STATUS_NOTFOUND; - struct ent_context ctx; + struct ent_context context; _nss_ldap_enter(); log_log(LOG_DEBUG,"==> _nss_ldap_getbyname (base=\"%s\", filter=\"%s\"",base,filter); - ctx.ec_msgid=-1; - ctx.ec_cookie=NULL; + _nss_ldap_ent_context_init_locked(&context); - stat=_nss_ldap_search_s(base,filter,sel,attrs,1,&ctx.ec_res); + stat=_nss_ldap_search_s(base,filter,sel,attrs,1,&context.ec_res); if (stat!=NSS_STATUS_SUCCESS) { _nss_ldap_leave (); @@ -2144,13 +2059,13 @@ int _nss_ldap_getbyname(void *result, char *buffer, size_t buflen, * 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=NULL /*was: args->la_arg2.la_string*/; + LS_INIT(context.ec_state); + context.ec_state.ls_type=LS_TYPE_KEY; + context.ec_state.ls_info.ls_key=NULL /*was: args->la_arg2.la_string*/; - stat=do_parse_s(&ctx,result,buffer,buflen,errnop,parser); + stat=do_parse_s(&context,result,buffer,buflen,errnop,parser); - _nss_ldap_ent_context_release(&ctx); + _nss_ldap_ent_context_cleanup(&context); log_log(LOG_DEBUG,"<== _nss_ldap_getbyname"); @@ -2160,7 +2075,7 @@ int _nss_ldap_getbyname(void *result, char *buffer, size_t buflen, return nss2nslcd(stat); } -static int NEW_do_parse_s(struct ent_context *ctx,TFILE *fp,NEWparser_t parser) +static int NEW_do_parse_s(struct ent_context *context,TFILE *fp,NEWparser_t parser) { int parseStat=NSLCD_RESULT_NOTFOUND; LDAPMessage *e=NULL; @@ -2173,12 +2088,12 @@ static int NEW_do_parse_s(struct ent_context *ctx,TFILE *fp,NEWparser_t parser) */ 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 ((context->ec_state.ls_retry==0) && + ( (context->ec_state.ls_type==LS_TYPE_KEY) || + (context->ec_state.ls_info.ls_index==-1) )) { if (e == NULL) - e = ldap_first_entry (__session.ls_conn, ctx->ec_res); + e = ldap_first_entry (__session.ls_conn,context->ec_res); else e = ldap_next_entry (__session.ls_conn, e); } @@ -2197,9 +2112,9 @@ static int NEW_do_parse_s(struct ent_context *ctx,TFILE *fp,NEWparser_t parser) * find one which is parseable, or exhaust avialable * entries, whichever is first. */ - parseStat=parser(e,&ctx->ec_state,fp); + parseStat=parser(e,&context->ec_state,fp); /* hold onto the state if we're out of memory XXX */ - ctx->ec_state.ls_retry=0; + context->ec_state.ls_retry=0; } while (parseStat==NSLCD_RESULT_NOTFOUND); return parseStat; @@ -2211,15 +2126,14 @@ int _nss_ldap_searchbyname( enum ldap_map_selector sel,const char **attrs,TFILE *fp,NEWparser_t parser) { int stat; - struct ent_context ctx; + struct ent_context context; int32_t tmpint32; _nss_ldap_enter(); - ctx.ec_msgid=-1; - ctx.ec_cookie=NULL; + _nss_ldap_ent_context_init_locked(&context); - stat=nss2nslcd(_nss_ldap_search_s(base,filter,sel,attrs,1,&ctx.ec_res)); + stat=nss2nslcd(_nss_ldap_search_s(base,filter,sel,attrs,1,&context.ec_res)); /* write the result code */ WRITE_INT32(fp,stat); /* bail on nothing found */ @@ -2229,9 +2143,9 @@ int _nss_ldap_searchbyname( return 1; } /* call the parser for the result */ - stat=NEW_do_parse_s(&ctx,fp,parser); + stat=NEW_do_parse_s(&context,fp,parser); - _nss_ldap_ent_context_release(&ctx); + _nss_ldap_ent_context_cleanup(&context); /* moved unlock here to avoid race condition bug #49 */ _nss_ldap_leave(); |