示例#1
0
文件: request.c 项目: andreiw/polaris
/* returns an LDAP error code */
int
nsldapi_append_referral( LDAP *ld, char **referralsp, char *s )
{
	int	first;

	if ( *referralsp == NULL ) {
		first = 1;
		*referralsp = (char *)NSLDAPI_MALLOC( strlen( s ) +
		    LDAP_REF_STR_LEN + 1 );
	} else {
		first = 0;
		*referralsp = (char *)NSLDAPI_REALLOC( *referralsp,
		    strlen( *referralsp ) + strlen( s ) + 2 );
	}

	if ( *referralsp == NULL ) {
		return( LDAP_NO_MEMORY );
	}

	if ( first ) {
		strcpy( *referralsp, LDAP_REF_STR );
	} else {
		strcat( *referralsp, "\n" );
	}
	strcat( *referralsp, s );

	return( LDAP_SUCCESS );
}
示例#2
0
static int break_into_words(char *str, char *delims, char ***wordsp) {
  char *word, **words;
  int count;
  char *lasts;

  if ((words = (char **)NSLDAPI_CALLOC(1, sizeof(char *))) == NULL) {
    return (-1);
  }
  count = 0;
  words[count] = NULL;

  word = ldap_utf8strtok_r(str, delims, &lasts);
  while (word != NULL) {
    if ((words = (char **)NSLDAPI_REALLOC(
             words, (count + 2) * sizeof(char *))) == NULL) {
      return (-1);
    }

    words[count] = word;
    words[++count] = NULL;
    word = ldap_utf8strtok_r(NULL, delims, &lasts);
  }

  *wordsp = words;
  return (count);
}
示例#3
0
LDAP_CALL
ldap_explode_dns( const char *dn )
{
	int	ncomps, maxcomps;
	char	*s, *cpydn;
	char	**rdns;
#ifdef HAVE_STRTOK_R	/* defined in portable.h */
	char	*lasts;
#endif

	if ( dn == NULL ) {
		dn = "";
	}

	if ( (rdns = (char **)NSLDAPI_MALLOC( 8 * sizeof(char *) )) == NULL ) {
		return( NULL );
	}

	maxcomps = 8;
	ncomps = 0;
	cpydn = nsldapi_strdup( (char *)dn );
	for ( s = STRTOK( cpydn, "@.", &lasts ); s != NULL;
	    s = STRTOK( NULL, "@.", &lasts ) ) {
		if ( ncomps == maxcomps ) {
			maxcomps *= 2;
			if ( (rdns = (char **)NSLDAPI_REALLOC( rdns, maxcomps *
			    sizeof(char *) )) == NULL ) {
				NSLDAPI_FREE( cpydn );
				return( NULL );
			}
		}
		rdns[ncomps++] = nsldapi_strdup( s );
	}
	rdns[ncomps] = NULL;
	NSLDAPI_FREE( cpydn );

	return( rdns );
}
示例#4
0
/*
 * Abandon all outstanding requests for msgid (included child requests
 * spawned when chasing referrals).  This function calls itself recursively.
 * No locking is done is this function so it must be done by the caller.
 * Returns an LDAP error code and sets it in LDAP *ld as well
 */
static int do_abandon(LDAP *ld, int origid, int msgid,
                      LDAPControl **serverctrls, LDAPControl **clientctrls) {
  BerElement *ber;
  int i, bererr, lderr, sendabandon;
  LDAPRequest *lr = NULL;

  /*
   * An abandon request looks like this:
   * AbandonRequest ::= MessageID
   */
  LDAPDebug(LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n", origid, msgid,
            0);

  /* optimistic */
  lderr = LDAP_SUCCESS;

  /*
   * Find the request that we are abandoning.  Don't send an
   * abandon message unless there is something to abandon.
   */
  sendabandon = 0;
  for (lr = ld->ld_requests; lr != NULL; lr = lr->lr_next) {
    if (lr->lr_msgid == msgid) { /* this message */
      if (origid == msgid && lr->lr_parent != NULL) {
        /* don't let caller abandon child requests! */
        lderr = LDAP_PARAM_ERROR;
        goto set_errorcode_and_return;
      }
      if (lr->lr_status == LDAP_REQST_INPROGRESS) {
        /*
         * We only need to send an abandon message if
         * the request is in progress.
         */
        sendabandon = 1;
      }
      break;
    }
    if (lr->lr_origid == msgid) { /* child:  abandon it */
      (void)do_abandon(ld, msgid, lr->lr_msgid, serverctrls, clientctrls);
      /* we ignore errors from child abandons... */
    }
  }

  if (ldap_msgdelete(ld, msgid) == 0) {
    /* we had all the results and deleted them */
    goto set_errorcode_and_return;
  }

  if (lr != NULL && sendabandon) {
    /* create a message to send */
    if ((lderr = nsldapi_alloc_ber_with_options(ld, &ber)) == LDAP_SUCCESS) {
      int abandon_msgid;

      LDAP_MUTEX_LOCK(ld, LDAP_MSGID_LOCK);
      abandon_msgid = ++ld->ld_msgid;
      LDAP_MUTEX_UNLOCK(ld, LDAP_MSGID_LOCK);
#ifdef CLDAP
      if (ld->ld_dbp->sb_naddr > 0) {
        bererr = ber_printf(ber, "{isti", abandon_msgid, ld->ld_cldapdn,
                            LDAP_REQ_ABANDON, msgid);
      } else {
#endif /* CLDAP */
        bererr =
            ber_printf(ber, "{iti", abandon_msgid, LDAP_REQ_ABANDON, msgid);
#ifdef CLDAP
      }
#endif /* CLDAP */

      if (bererr == -1 || (lderr = nsldapi_put_controls(ld, serverctrls, 1,
                                                        ber)) != LDAP_SUCCESS) {
        lderr = LDAP_ENCODING_ERROR;
        ber_free(ber, 1);
      } else {
        /* try to send the message */
        lderr =
            nsldapi_send_abandon_message(ld, lr->lr_conn, ber, abandon_msgid);
      }
    }
  }

  if (lr != NULL) {
    /*
     * Always call nsldapi_free_connection() so that the connection's
     * ref count is correctly decremented.  It is OK to always pass
     * 1 for the "unbind" parameter because doing so will only affect
     * connections that resulted from a child request (because the
     * default connection's ref count never goes to zero).
     */
    nsldapi_free_connection(ld, lr->lr_conn, NULL, NULL, 0 /* do not force */,
                            1 /* send unbind before closing */);

    /*
     * Free the entire request chain if we finished abandoning everything.
     */
    if (origid == msgid) {
      nsldapi_free_request(ld, lr, 0);
    }
  }

  /*
   * Record the abandoned message ID (used to discard any server responses
   * that arrive later).
   */
  LDAP_MUTEX_LOCK(ld, LDAP_ABANDON_LOCK);
  if (ld->ld_abandoned == NULL) {
    if ((ld->ld_abandoned = (int *)NSLDAPI_MALLOC(2 * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
    i = 0;
  } else {
    for (i = 0; ld->ld_abandoned[i] != -1; i++)
      ; /* NULL */
    if ((ld->ld_abandoned = (int *)NSLDAPI_REALLOC(
             (char *)ld->ld_abandoned, (i + 2) * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
  }
  ld->ld_abandoned[i] = msgid;
  ld->ld_abandoned[i + 1] = -1;
  LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);

set_errorcode_and_return:
  LDAP_SET_LDERRNO(ld, lderr, NULL, NULL);
  return (lderr);
}
示例#5
0
/*
 * Pull controls out of "ber" (if any present) and return them in "controlsp."
 * Returns an LDAP error code.
 */
int
nsldapi_get_controls( BerElement *ber, LDAPControl ***controlsp )
{
	LDAPControl		*newctrl;
	ber_tag_t		tag;
	ber_len_t		len;
	int			rc, maxcontrols, curcontrols;
	char			*last;

	/*
	 * Each LDAPMessage can have a set of controls appended
	 * to it. Controls are used to extend the functionality
	 * of an LDAP operation (e.g., add an attribute size limit
	 * to the search operation). These controls look like this:
	 *
	 *	Controls ::= SEQUENCE OF Control
	 *
	 *	Control ::= SEQUENCE {
	 *		controlType	LDAPOID,
	 *		criticality	BOOLEAN DEFAULT FALSE,
	 *		controlValue	OCTET STRING
	 *	}
	 */
	LDAPDebug( LDAP_DEBUG_TRACE, "=> nsldapi_get_controls\n", 0, 0, 0 );

	*controlsp = NULL;

	/*
         * check to see if controls were included
	 */
	if ( ber_get_option( ber, LBER_OPT_REMAINING_BYTES, &len ) != 0 ) {
		return( LDAP_DECODING_ERROR );	/* unexpected error */
	}
	if ( len == 0 ) {
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "<= nsldapi_get_controls no controls\n", 0, 0, 0 );
		return( LDAP_SUCCESS );			/* no controls */
	}
	if (( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
		if ( tag == LBER_ERROR ) {
			LDAPDebug( LDAP_DEBUG_TRACE,
			    "<= nsldapi_get_controls LDAP_PROTOCOL_ERROR\n",
			    0, 0, 0 );
			return( LDAP_DECODING_ERROR );	/* decoding error */
		}
		/*
		 * We found something other than controls.  This should never
		 * happen in LDAPv3, but we don't treat this is a hard error --
		 * we just ignore the extra stuff.
		 */
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "<= nsldapi_get_controls ignoring unrecognized data in message (tag 0x%x)\n",
		    tag, 0, 0 );
		return( LDAP_SUCCESS );
	}

	maxcontrols = curcontrols = 0;
	for ( tag = ber_first_element( ber, &len, &last );
	    tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
	    tag = ber_next_element( ber, &len, last ) ) {
		if ( curcontrols >= maxcontrols - 1 ) {
#define CONTROL_GRABSIZE	5
			maxcontrols += CONTROL_GRABSIZE;
			*controlsp = (struct ldapcontrol **)NSLDAPI_REALLOC(
			    (char *)*controlsp, maxcontrols *
			    sizeof(struct ldapcontrol *) );
			if ( *controlsp == NULL ) {
			    rc = LDAP_NO_MEMORY;
			    goto free_and_return;
			}
		}
		if (( newctrl = (struct ldapcontrol *)NSLDAPI_CALLOC( 1,
		    sizeof(LDAPControl))) == NULL ) {
			rc = LDAP_NO_MEMORY;
			goto free_and_return;
		}
		
		(*controlsp)[curcontrols++] = newctrl;
		(*controlsp)[curcontrols] = NULL;

		if ( ber_scanf( ber, "{a", &newctrl->ldctl_oid )
		    == LBER_ERROR ) {
			rc = LDAP_DECODING_ERROR;
			goto free_and_return;
		}

		/* the criticality is optional */
		if ( ber_peek_tag( ber, &len ) == LBER_BOOLEAN ) {
			int		aint;

			if ( ber_scanf( ber, "b", &aint ) == LBER_ERROR ) {
				rc = LDAP_DECODING_ERROR;
				goto free_and_return;
			}
			newctrl->ldctl_iscritical = (char)aint;	/* XXX lossy cast */
		} else {
			/* absent is synonomous with FALSE */
			newctrl->ldctl_iscritical = 0;
		}

		/* the control value is optional */
		if ( ber_peek_tag( ber, &len ) == LBER_OCTETSTRING ) {
			if ( ber_scanf( ber, "o", &newctrl->ldctl_value )
			    == LBER_ERROR ) {
				rc = LDAP_DECODING_ERROR;
				goto free_and_return;
			}
		} else {
			(newctrl->ldctl_value).bv_val = NULL;
			(newctrl->ldctl_value).bv_len = 0;
		}

	}

	if ( tag == LBER_ERROR ) {
		rc = LDAP_DECODING_ERROR;
		goto free_and_return;
	}

	LDAPDebug( LDAP_DEBUG_TRACE,
	    "<= nsldapi_get_controls found %d controls\n", curcontrols, 0, 0 );
	return( LDAP_SUCCESS );

free_and_return:;
	ldap_controls_free( *controlsp );
	*controlsp = NULL;
	LDAPDebug( LDAP_DEBUG_TRACE,
	    "<= nsldapi_get_controls error 0x%x\n", rc, 0, 0 );
	return( rc );
}
示例#6
0
LDAP_CALL
ldap_tmplattrs( struct ldap_disptmpl *tmpl, char **includeattrs,
                int exclude, unsigned long syntaxmask )
{
    /*
     * this routine should filter out duplicate attributes...
     */
    struct ldap_tmplitem	*tirowp, *ticolp;
    int			i, attrcnt, memerr;
    char		**attrs;

    attrcnt = 0;
    memerr = 0;

    if (( attrs = (char **)NSLDAPI_MALLOC( sizeof( char * ))) == NULL ) {
        return( NULL );
    }

    if ( includeattrs != NULL ) {
        for ( i = 0; !memerr && includeattrs[ i ] != NULL; ++i ) {
            if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 ) *
                                                    sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
                                                            nsldapi_strdup( includeattrs[ i ] )) == NULL ) {
                memerr = 1;
            } else {
                attrs[ attrcnt ] = NULL;
            }
        }
    }

    for ( tirowp = ldap_first_tmplrow( tmpl );
            !memerr && tirowp != NULLTMPLITEM;
            tirowp = ldap_next_tmplrow( tmpl, tirowp )) {
        for ( ticolp = ldap_first_tmplcol( tmpl, tirowp );
                ticolp != NULLTMPLITEM;
                ticolp = ldap_next_tmplcol( tmpl, tirowp, ticolp )) {

            if ( syntaxmask != 0 ) {
                if (( exclude &&
                        ( syntaxmask & ticolp->ti_syntaxid ) != 0 ) ||
                        ( !exclude &&
                          ( syntaxmask & ticolp->ti_syntaxid ) == 0 )) {
                    continue;
                }
            }

            if ( ticolp->ti_attrname != NULL ) {
                if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 )
                                                        * sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
                                                                nsldapi_strdup( ticolp->ti_attrname )) == NULL ) {
                    memerr = 1;
                } else {
                    attrs[ attrcnt ] = NULL;
                }
            }
        }
    }

    if ( memerr || attrcnt == 0 ) {
        for ( i = 0; i < attrcnt; ++i ) {
            if ( attrs[ i ] != NULL ) {
                NSLDAPI_FREE( attrs[ i ] );
            }
        }

        NSLDAPI_FREE( (char *)attrs );
        return( NULL );
    }

    return( attrs );
}