int Ldap_get_filter_list( BerElement *ber, char *text ) { //Filter **new; int err; ber_tag_t tag; ber_len_t len; char *last; char textbuf[128]; //new=f; for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { err = Ldap_get_filter( ber, text); if ( err != LDAP_SUCCESS ) { printf("Ldap_get_Filter_list Error \n\n"); //new = &(*new)->f_next; return( err ); } } //printf("Debug: 1 time get_list OK!\n"); return( LDAP_SUCCESS ); }
/*********************************************************************** * ber_first_element (WLDAP32.@) * * Return the tag of the first element in a set or sequence. * * PARAMS * berelement [I] Pointer to a berelement structure. * len [O] Receives the length of the first element. * opaque [O] Receives a pointer to a cookie. * * RETURNS * Success: Tag of the first element. * Failure: LBER_DEFAULT (no more data). * * NOTES * len and cookie should be passed to ber_next_element. */ ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR **opaque ) { #ifdef HAVE_LDAP return ber_first_element( berelement, len, opaque ); #else return LBER_ERROR; #endif }
static int count_key(BerElement *ber) { char *end; ber_len_t len; ber_tag_t tag; int count = 0; /* Server Side Sort Control is a SEQUENCE of SEQUENCE */ for ( tag = ber_first_element( ber, &len, &end ); tag == LBER_SEQUENCE; tag = ber_next_element( ber, &len, end )) { tag = ber_skip_tag( ber, &len ); ber_skip_data( ber, len ); ++count; } ber_rewind( ber ); return count; }
int checkModReq(BerElement *ber) { /* * Parse the modify request. It looks like this: * * ModifyRequest := [APPLICATION 6] SEQUENCE { * name DistinguishedName, * mods SEQUENCE OF SEQUENCE { * operation ENUMERATED { * add (0), * delete (1), * replace (2) * }, * modification SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } * } */ struct berval dn = BER_BVNULL; char textbuf[ SLAP_TEXT_BUFLEN ]; size_t textlen = sizeof( textbuf ); ber_tag_t tag; ber_len_t len; char *last; int rc; rc = LDAP_SUCCESS; /* get the name */ if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) { printf(">>Error<< MOD DN Decode Error.\n"); return -1; } printf("|-MOD DN:\t%s\n", dn.bv_val); for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ){ ber_int_t mop; Modifications tmp, *mod; tmp.sml_nvalues = NULL; if ( ber_scanf( ber, "{e{m[W]}}", &mop, &tmp.sml_type, &tmp.sml_values ) == LBER_ERROR ) { printf(">>Error<< MOD Attr list Decode Error\n"); return -1; } printf("|--Mod Type:\t%s\n", LdapModTypeStr[mop]); if(tmp.sml_values == NULL){ //Delete would be with a value printf("|---%s\n", tmp.sml_type.bv_val); }else{ printf("|---%s:\t%s\n", tmp.sml_type.bv_val, tmp.sml_values->bv_val); } } return rc; }
static int ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, struct berval *bdn ) { struct berval a; BerElement ber = *ldap_get_message_ber( e ); Attribute *attr, **attrp; const char *text; int last; char *lastb; ber_len_t len; /* safe assumptions ... */ assert( ent != NULL ); BER_BVZERO( &ent->e_bv ); if ( ber_scanf( &ber, "{m", bdn ) == LBER_ERROR ) { return LDAP_DECODING_ERROR; } /* * Note: this may fail if the target host(s) schema differs * from the one known to the meta, and a DN with unknown * attributes is returned. * * FIXME: should we log anything, or delegate to dnNormalize? */ /* Note: if the distinguished values or the naming attributes * change, should we massage them as well? */ if ( dnPrettyNormal( NULL, bdn, &ent->e_name, &ent->e_nname, op->o_tmpmemctx ) != LDAP_SUCCESS ) { return LDAP_INVALID_DN_SYNTAX; } ent->e_attrs = NULL; if ( ber_first_element( &ber, &len, &lastb ) != LBER_SEQUENCE ) { return LDAP_SUCCESS; } attrp = &ent->e_attrs; while ( ber_next_element( &ber, &len, lastb ) == LBER_SEQUENCE && ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) { int i; slap_syntax_validate_func *validate; slap_syntax_transform_func *pretty; attr = attr_alloc( NULL ); if ( attr == NULL ) { return LDAP_OTHER; } if ( slap_bv2ad( &a, &attr->a_desc, &text ) != LDAP_SUCCESS ) { if ( slap_bv2undef_ad( &a, &attr->a_desc, &text, SLAP_AD_PROXIED ) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s ldap_build_entry: " "slap_bv2undef_ad(%s): %s\n", op->o_log_prefix, a.bv_val, text ); ( void )ber_scanf( &ber, "x" /* [W] */ ); attr_free( attr ); continue; } } /* no subschemaSubentry */ if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry || attr->a_desc == slap_schema.si_ad_entryDN ) { /* * We eat target's subschemaSubentry because * a search for this value is likely not * to resolve to the appropriate backend; * later, the local subschemaSubentry is * added. * * We also eat entryDN because the frontend * will reattach it without checking if already * present... */ ( void )ber_scanf( &ber, "x" /* [W] */ ); attr_free( attr ); continue; } if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR || attr->a_vals == NULL ) { /* * Note: attr->a_vals can be null when using * values result filter */ attr->a_vals = (struct berval *)&slap_dummy_bv; } validate = attr->a_desc->ad_type->sat_syntax->ssyn_validate; pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty; if ( !validate && !pretty ) { attr->a_nvals = NULL; attr_free( attr ); goto next_attr; } for ( i = 0; !BER_BVISNULL( &attr->a_vals[i] ); i++ ) ; last = i; /* * check that each value is valid per syntax * and pretty if appropriate */ for ( i = 0; i<last; i++ ) { struct berval pval; int rc; if ( pretty ) { rc = ordered_value_pretty( attr->a_desc, &attr->a_vals[i], &pval, NULL ); } else { rc = ordered_value_validate( attr->a_desc, &attr->a_vals[i], 0 ); } if ( rc != LDAP_SUCCESS ) { ObjectClass *oc; /* check if, by chance, it's an undefined objectClass */ if ( attr->a_desc == slap_schema.si_ad_objectClass && ( oc = oc_bvfind_undef( &attr->a_vals[i] ) ) != NULL ) { ber_dupbv( &pval, &oc->soc_cname ); rc = LDAP_SUCCESS; } else { ber_memfree( attr->a_vals[i].bv_val ); if ( --last == i ) { BER_BVZERO( &attr->a_vals[i] ); break; } attr->a_vals[i] = attr->a_vals[last]; BER_BVZERO( &attr->a_vals[last] ); i--; } } if ( rc == LDAP_SUCCESS && pretty ) { ber_memfree( attr->a_vals[i].bv_val ); attr->a_vals[i] = pval; } } attr->a_numvals = last = i; if ( last == 0 && attr->a_vals != &slap_dummy_bv ) { attr->a_nvals = NULL; attr_free( attr ); goto next_attr; } if ( last && attr->a_desc->ad_type->sat_equality && attr->a_desc->ad_type->sat_equality->smr_normalize ) { attr->a_nvals = ch_malloc( ( last + 1 )*sizeof( struct berval ) ); for ( i = 0; i < last; i++ ) { int rc; rc = ordered_value_normalize( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, attr->a_desc, attr->a_desc->ad_type->sat_equality, &attr->a_vals[i], &attr->a_nvals[i], NULL ); if ( rc != LDAP_SUCCESS ) { ber_memfree( attr->a_vals[i].bv_val ); if ( --last == i ) { BER_BVZERO( &attr->a_vals[i] ); break; } attr->a_vals[i] = attr->a_vals[last]; BER_BVZERO( &attr->a_vals[last] ); i--; } } BER_BVZERO( &attr->a_nvals[i] ); if ( last == 0 ) { attr_free( attr ); goto next_attr; } } else { attr->a_nvals = attr->a_vals; } attr->a_numvals = last; /* Handle sorted vals, strip dups but keep the attr */ if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) { while ( attr->a_numvals > 1 ) { int rc = slap_sort_vals( (Modifications *)attr, &text, &i, op->o_tmpmemctx ); if ( rc != LDAP_TYPE_OR_VALUE_EXISTS ) break; /* Strip duplicate values */ if ( attr->a_nvals != attr->a_vals ) ber_memfree( attr->a_nvals[i].bv_val ); ber_memfree( attr->a_vals[i].bv_val ); attr->a_numvals--; assert( i >= 0 ); if ( (unsigned)i < attr->a_numvals ) { attr->a_vals[i] = attr->a_vals[attr->a_numvals]; if ( attr->a_nvals != attr->a_vals ) attr->a_nvals[i] = attr->a_nvals[attr->a_numvals]; } BER_BVZERO(&attr->a_vals[attr->a_numvals]); if ( attr->a_nvals != attr->a_vals ) BER_BVZERO(&attr->a_nvals[attr->a_numvals]); } attr->a_flags |= SLAP_ATTR_SORTED_VALS; } *attrp = attr; attrp = &attr->a_next; next_attr:; } return LDAP_SUCCESS; }
static int cldap_parsemsg( LDAP *ld, int msgid, BerElement *ber, LDAPMessage **res, char *base ) { unsigned int tag, len; int rc; size_t baselen, slen; char *dn, *p, *cookie; LDAPMessage *chain, *prev, *ldm; struct berval *bv; rc = LDAP_DECODING_ERROR; /* pessimistic */ ldm = chain = prev = NULLMSG; baselen = ( base == NULL ) ? 0 : strlen( base ); bv = NULL; for ( tag = ber_first_element( ber, &len, &cookie ); tag != LBER_DEFAULT && rc != LDAP_SUCCESS; tag = ber_next_element( ber, &len, cookie )) { if (( ldm = (LDAPMessage *)calloc( 1, sizeof(LDAPMessage))) == NULL || ( ldm->lm_ber = alloc_ber_with_options( ld )) == NULLBER ) { rc = LDAP_NO_MEMORY; break; /* return w/error*/ } ldm->lm_msgid = msgid; ldm->lm_msgtype = tag; if ( tag == LDAP_RES_SEARCH_RESULT ) { Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 125, "cldap_parsemsg got search result\n"), 0, 0, 0 ); if ( ber_get_stringal( ber, &bv ) == LBER_DEFAULT ) { break; /* return w/error */ } if ( ber_printf( ldm->lm_ber, "to", tag, bv->bv_val, bv->bv_len ) == -1 ) { break; /* return w/error */ } ber_bvfree( bv ); bv = NULL; rc = LDAP_SUCCESS; } else if ( tag == LDAP_RES_SEARCH_ENTRY ) { if ( ber_scanf( ber, "{aO", &dn, &bv ) == LBER_ERROR ) { break; /* return w/error */ } Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 126, "cldap_parsemsg entry %s\n"), dn, 0, 0 ); if ( dn != NULL && *(dn + ( slen = strlen(dn)) - 1) == '*' && baselen > 0 ) { /* * substitute original searchbase for trailing '*' */ if (( p = (char *)malloc( slen + baselen )) == NULL ) { rc = LDAP_NO_MEMORY; free( dn ); break; /* return w/error */ } strcpy( p, dn ); strcpy( p + slen - 1, base ); free( dn ); dn = p; } if ( ber_printf( ldm->lm_ber, "t{so}", tag, dn, bv->bv_val, bv->bv_len ) == -1 ) { break; /* return w/error */ } free( dn ); ber_bvfree( bv ); bv = NULL; } else { Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 127, "cldap_parsemsg got unknown tag %d\n"), tag, 0, 0 ); rc = LDAP_PROTOCOL_ERROR; break; /* return w/error */ } /* Reset message ber so we can read from it later. Gack! */ ldm->lm_ber->ber_end = ldm->lm_ber->ber_ptr; ldm->lm_ber->ber_ptr = ldm->lm_ber->ber_buf; #ifdef LDAP_DEBUG if ( ldap_debug & LDAP_DEBUG_PACKETS ) { fprintf( stderr, "cldap_parsemsg add message id %d type %d:\n", ldm->lm_msgid, ldm->lm_msgtype ); ber_dump( ldm->lm_ber, 1 ); } #endif /* LDAP_DEBUG */ #ifndef NO_CACHE if ( ld->ld_cache != NULL ) { add_result_to_cache( ld, ldm ); } #endif /* NO_CACHE */ if ( chain == NULL ) { chain = ldm; } else { prev->lm_chain = ldm; } prev = ldm; ldm = NULL; } /* dispose of any leftovers */ if ( ldm != NULL ) { if ( ldm->lm_ber != NULLBER ) { ber_free( ldm->lm_ber, 1 ); } free( ldm ); } if ( bv != NULL ) { ber_bvfree( bv ); } /* return chain, calling result2error if we got anything at all */ *res = chain; return(( *res == NULLMSG ) ? rc : ldap_result2error( ld, *res, 0 )); }
int checkADDReq(BerElement *ber) { /* * Parse the add request. It looks like this: * * AddRequest := [APPLICATION 14] SEQUENCE { * name DistinguishedName, * attrs SEQUENCE OF SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } */ BerElement *ber1 = ber; char *last; struct berval dn = BER_BVNULL; ber_len_t len; ber_tag_t tag; Modifications *modlist = NULL; Modifications **modtail = &modlist; Modifications tmp; char textbuf[ SLAP_TEXT_BUFLEN ]; size_t textlen = sizeof( textbuf ); int rc = 0; int freevals = 1; /* get the name */ if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) { printf(">>Error<< ADD DN Decode Error.\n"); return -1; } printf("|-ADD DN:\t%s\n", dn.bv_val); printf("|-ADD Attributes list:\n"); /* get the attrs */ for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { Modifications *mod; ber_tag_t rtag; tmp.sml_nvalues = NULL; rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_values ); if ( rtag == LBER_ERROR ) { printf(">>Error<< ADD Attribute Decode Error.\n"); return -1; } if ( tmp.sml_values == NULL ) { printf("Ber decode ADD opt No value found.\n"); return -1; } if(tmp.sml_values == NULL){ printf("|---%s\n", tmp.sml_type.bv_val); }else{ printf("|--%s:\t%s\n", tmp.sml_type.bv_val, tmp.sml_values->bv_val ); } } }
/* * Get an annotated value from the BerElement. Returns 0 on * success, -1 on failure. */ static int my_ber_scanf_value(BerElement *ber, Slapi_Value **value, PRBool *deleted) { struct berval *attrval = NULL; ber_len_t len = -1; ber_tag_t tag; CSN *csn = NULL; char csnstring[CSN_STRSIZE + 1]; CSNType csntype; char *lasti; PR_ASSERT(ber && value && deleted); if (NULL == ber && NULL == value) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 1\n"); goto loser; } *value = NULL; /* Each value is a sequence */ if (ber_scanf(ber, "{O", &attrval) == LBER_ERROR) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 2\n"); goto loser; } /* Allocate and fill in the attribute value */ if ((*value = slapi_value_new_berval(attrval)) == NULL) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 3\n"); goto loser; } /* check if this is a deleted value */ if (ber_peek_tag(ber, &len) == LBER_BOOLEAN) { if (ber_scanf(ber, "b", deleted) == LBER_ERROR) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 4\n"); goto loser; } } else /* default is present value */ { *deleted = PR_FALSE; } /* Read the sequence of CSNs */ for (tag = ber_first_element(ber, &len, &lasti); tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET; tag = ber_next_element(ber, &len, lasti)) { ber_int_t csntype_tmp; /* Each CSN is in a sequence that includes a csntype and CSN */ len = CSN_STRSIZE; if (ber_scanf(ber, "{es}", &csntype_tmp, csnstring, &len) == LBER_ERROR) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 7 - bval is %s\n", attrval->bv_val); goto loser; } switch (csntype_tmp) { case CSN_TYPE_VALUE_UPDATED_ON_WIRE: csntype = CSN_TYPE_VALUE_UPDATED; break; case CSN_TYPE_VALUE_DELETED_ON_WIRE: csntype = CSN_TYPE_VALUE_DELETED; break; case CSN_TYPE_VALUE_DISTINGUISHED_ON_WIRE: csntype = CSN_TYPE_VALUE_DISTINGUISHED; break; default: slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Error: preposterous CSN type " "%d received during total update.\n", csntype_tmp); goto loser; } csn = csn_new_by_string(csnstring); if (csn == NULL) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 8\n"); goto loser; } value_add_csn(*value, csntype, csn); csn_free (&csn); } if (ber_scanf(ber, "}") == LBER_ERROR) /* End of annotated attribute value seq */ { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 10\n"); goto loser; } if (attrval) ber_bvfree(attrval); return 0; loser: /* Free any stuff we allocated */ if (csn) csn_free (&csn); if (attrval) ber_bvfree(attrval); if (value) { slapi_value_free (value); } return -1; }
/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN. * x509_name must be raw DER. If func is non-NULL, the * constructed DN will use numeric OIDs to identify attributeTypes, * and the func() will be invoked to rewrite the DN with the given * flags. * * Otherwise the DN will use shortNames from a hardcoded table. */ int ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, unsigned flags ) { LDAPDN newDN; LDAPRDN newRDN; LDAPAVA *newAVA, *baseAVA; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; char oids[8192], *oidptr = oids, *oidbuf = NULL; void *ptrs[2048]; char *dn_end, *rdn_end; int i, navas, nrdns, rc = LDAP_SUCCESS; size_t dnsize, oidrem = sizeof(oids), oidsize = 0; int csize; ber_tag_t tag; ber_len_t len; oid_name *oidname; struct berval Oid, Val, oid2, *in = x509_name; assert( bv != NULL ); bv->bv_len = 0; bv->bv_val = NULL; navas = 0; nrdns = 0; /* A DN is a SEQUENCE of RDNs. An RDN is a SET of AVAs. * An AVA is a SEQUENCE of attr and value. * Count the number of AVAs and RDNs */ ber_init2( ber, in, LBER_USE_DER ); tag = ber_peek_tag( ber, &len ); if ( tag != LBER_SEQUENCE ) return LDAP_DECODING_ERROR; for ( tag = ber_first_element( ber, &len, &dn_end ); tag == LBER_SET; tag = ber_next_element( ber, &len, dn_end )) { nrdns++; for ( tag = ber_first_element( ber, &len, &rdn_end ); tag == LBER_SEQUENCE; tag = ber_next_element( ber, &len, rdn_end )) { tag = ber_skip_tag( ber, &len ); ber_skip_data( ber, len ); navas++; } } /* Allocate the DN/RDN/AVA stuff as a single block */ dnsize = sizeof(LDAPRDN) * (nrdns+1); dnsize += sizeof(LDAPAVA *) * (navas+nrdns); dnsize += sizeof(LDAPAVA) * navas; if (dnsize > sizeof(ptrs)) { newDN = (LDAPDN)LDAP_MALLOC( dnsize ); if ( newDN == NULL ) return LDAP_NO_MEMORY; } else { newDN = (LDAPDN)(char *)ptrs; } newDN[nrdns] = NULL; newRDN = (LDAPRDN)(newDN + nrdns+1); newAVA = (LDAPAVA *)(newRDN + navas + nrdns); baseAVA = newAVA; /* Rewind and start extracting */ ber_rewind( ber ); tag = ber_first_element( ber, &len, &dn_end ); for ( i = nrdns - 1; i >= 0; i-- ) { newDN[i] = newRDN; for ( tag = ber_first_element( ber, &len, &rdn_end ); tag == LBER_SEQUENCE; tag = ber_next_element( ber, &len, rdn_end )) { *newRDN++ = newAVA; tag = ber_skip_tag( ber, &len ); tag = ber_get_stringbv( ber, &Oid, LBER_BV_NOTERM ); if ( tag != LBER_TAG_OID ) { rc = LDAP_DECODING_ERROR; goto nomem; } oid2.bv_val = oidptr; oid2.bv_len = oidrem; if ( ber_decode_oid( &Oid, &oid2 ) < 0 ) { rc = LDAP_DECODING_ERROR; goto nomem; } oidname = find_oid( &oid2 ); if ( !oidname ) { newAVA->la_attr = oid2; oidptr += oid2.bv_len + 1; oidrem -= oid2.bv_len + 1; /* Running out of OID buffer space? */ if (oidrem < 128) { if ( oidsize == 0 ) { oidsize = sizeof(oids) * 2; oidrem = oidsize; oidbuf = LDAP_MALLOC( oidsize ); if ( oidbuf == NULL ) goto nomem; oidptr = oidbuf; } else { char *old = oidbuf; oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 ); if ( oidbuf == NULL ) goto nomem; /* Buffer moved! Fix AVA pointers */ if ( old != oidbuf ) { LDAPAVA *a; long dif = oidbuf - old; for (a=baseAVA; a<=newAVA; a++){ if (a->la_attr.bv_val >= old && a->la_attr.bv_val <= (old + oidsize)) a->la_attr.bv_val += dif; } } oidptr = oidbuf + oidsize - oidrem; oidrem += oidsize; oidsize *= 2; } } } else { if ( func ) { newAVA->la_attr = oidname->oid; } else { newAVA->la_attr = oidname->name; } } newAVA->la_private = NULL; newAVA->la_flags = LDAP_AVA_STRING; tag = ber_get_stringbv( ber, &Val, LBER_BV_NOTERM ); switch(tag) { case LBER_TAG_UNIVERSAL: /* This uses 32-bit ISO 10646-1 */ csize = 4; goto to_utf8; case LBER_TAG_BMP: /* This uses 16-bit ISO 10646-1 */ csize = 2; goto to_utf8; case LBER_TAG_TELETEX: /* This uses 8-bit, assume ISO 8859-1 */ csize = 1; to_utf8: rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value ); newAVA->la_flags |= LDAP_AVA_NONPRINTABLE; allocd: newAVA->la_flags |= LDAP_AVA_FREE_VALUE; if (rc != LDAP_SUCCESS) goto nomem; break; case LBER_TAG_UTF8: newAVA->la_flags |= LDAP_AVA_NONPRINTABLE; /* This is already in UTF-8 encoding */ case LBER_TAG_IA5: case LBER_TAG_PRINTABLE: /* These are always 7-bit strings */ newAVA->la_value = Val; break; case LBER_BITSTRING: /* X.690 bitString value converted to RFC4517 Bit String */ rc = der_to_ldap_BitString( &Val, &newAVA->la_value ); goto allocd; default: /* Not a string type at all */ newAVA->la_flags = 0; newAVA->la_value = Val; break; } newAVA++; } *newRDN++ = NULL; tag = ber_next_element( ber, &len, dn_end ); } if ( func ) { rc = func( newDN, flags, NULL ); if ( rc != LDAP_SUCCESS ) goto nomem; } rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL ); nomem: for (;baseAVA < newAVA; baseAVA++) { if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR) LDAP_FREE( baseAVA->la_attr.bv_val ); if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE) LDAP_FREE( baseAVA->la_value.bv_val ); } if ( oidsize != 0 ) LDAP_FREE( oidbuf ); if ( newDN != (LDAPDN)(char *) ptrs ) LDAP_FREE( newDN ); return rc; }
int ldap_pvt_get_controls( BerElement *ber, LDAPControl ***ctrls ) { int nctrls; ber_tag_t tag; ber_len_t len; char *opaque; assert( ber != NULL ); if( ctrls == NULL ) { return LDAP_SUCCESS; } *ctrls = NULL; len = ber_pvt_ber_remaining( ber ); if( len == 0) { /* no controls */ return LDAP_SUCCESS; } if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) { if( tag == LBER_ERROR ) { /* decoding error */ return LDAP_DECODING_ERROR; } /* ignore unexpected input */ return LDAP_SUCCESS; } /* set through each element */ nctrls = 0; *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) ); if( *ctrls == NULL ) { return LDAP_NO_MEMORY; } *ctrls[nctrls] = NULL; for( tag = ber_first_element( ber, &len, &opaque ); tag != LBER_ERROR; tag = ber_next_element( ber, &len, opaque ) ) { LDAPControl *tctrl; LDAPControl **tctrls; tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) ); /* allocate pointer space for current controls (nctrls) * + this control + extra NULL */ tctrls = (tctrl == NULL) ? NULL : LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *)); if( tctrls == NULL ) { /* one of the above allocation failed */ if( tctrl != NULL ) { LDAP_FREE( tctrl ); } ldap_controls_free(*ctrls); *ctrls = NULL; return LDAP_NO_MEMORY; } tctrls[nctrls++] = tctrl; tctrls[nctrls] = NULL; tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid ); if( tag == LBER_ERROR ) { *ctrls = NULL; ldap_controls_free( tctrls ); return LDAP_DECODING_ERROR; } tag = ber_peek_tag( ber, &len ); if( tag == LBER_BOOLEAN ) { ber_int_t crit; tag = ber_scanf( ber, "b", &crit ); tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0; tag = ber_peek_tag( ber, &len ); } if( tag == LBER_OCTETSTRING ) { tag = ber_scanf( ber, "o", &tctrl->ldctl_value ); } else { BER_BVZERO( &tctrl->ldctl_value ); } *ctrls = tctrls; } return LDAP_SUCCESS; }
static int my_ber_scanf_attr (BerElement *ber, Slapi_Attr **attr, PRBool *deleted) { char *attrtype = NULL; CSN *attr_deletion_csn = NULL; PRBool val_deleted; char *lasti; ber_len_t len; ber_tag_t tag; char *str = NULL; int rc; Slapi_Value *value = NULL; if (attr == NULL) { goto loser; } PR_ASSERT (ber && attr && deleted); /* allocate the attribute */ *attr = slapi_attr_new (); if (*attr == NULL) { goto loser; } if (ber_scanf(ber, "{a", &attrtype) == LBER_ERROR) /* Begin sequence for this attr */ { goto loser; } slapi_attr_init(*attr, attrtype); slapi_ch_free ((void **)&attrtype); /* The attribute deletion CSN is next and is optional? */ if (ber_peek_tag(ber, &len) == LBER_OCTETSTRING) { if (ber_scanf(ber, "a", &str) == LBER_ERROR) { goto loser; } attr_deletion_csn = csn_new_by_string(str); slapi_ch_free((void **)&str); } if (attr_deletion_csn) { rc = attr_set_deletion_csn(*attr, attr_deletion_csn); csn_free (&attr_deletion_csn); if (rc != 0) { goto loser; } } /* The "attribute deleted" flag is next, and is optional */ if (ber_peek_tag(ber, &len) == LBER_BOOLEAN) { if (ber_scanf(ber, "b", deleted) == LBER_DEFAULT) { goto loser; } } else /* default is present */ { *deleted = PR_FALSE; } /* loop over the list of attribute values */ for (tag = ber_first_element(ber, &len, &lasti); tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET; tag = ber_next_element(ber, &len, lasti)) { value = NULL; if (my_ber_scanf_value(ber, &value, &val_deleted) == -1) { goto loser; } if (val_deleted) { /* Add the value to the attribute */ if (attr_add_deleted_value(*attr, value) == -1) /* attr has ownership of value */ { goto loser; } } else { /* Add the value to the attribute */ if (slapi_attr_add_value(*attr, value) == -1) /* attr has ownership of value */ { goto loser; } } if (value) slapi_value_free(&value); } if (ber_scanf(ber, "}") == LBER_ERROR) /* End sequence for this attribute */ { goto loser; } return 0; loser: if (attr && *attr) slapi_attr_free (attr); if (value) slapi_value_free (&value); slapi_ch_free_string(&attrtype); slapi_ch_free_string(&str); return -1; }
int ParseRequestControls( VDIR_OPERATION * op, VDIR_LDAP_RESULT * lr ) { int retVal = LDAP_SUCCESS; ber_tag_t tag = LBER_ERROR; ber_len_t len = 0; char * endOfCtrlsMarker = NULL; VDIR_LDAP_CONTROL ** control = &(op->reqControls); BerValue lberBervType = {0}; BerValue lberBervCtlValue = {0}; PSTR pszLocalErrorMsg = NULL; VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseRequestControls: Begin." ); *control = NULL; #ifndef _WIN32 if (ber_pvt_ber_remaining(op->ber) != 0) #else if (LBER_DEFAULT != ber_peek_tag (op->ber, &len)) #endif { if (ber_peek_tag( op->ber, &len ) != LDAP_TAG_CONTROLS ) { lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: Request controls expected, but something else is there in the PDU."); } // Get controls. ber_first_element => skip the sequence header, set the cursor at the 1st control in the SEQ of SEQ for( tag = ber_first_element( op->ber, &len, &endOfCtrlsMarker ); tag != LBER_ERROR; tag = ber_next_element( op->ber, &len, endOfCtrlsMarker ) ) { // m => in-place if (ber_scanf( op->ber, "{m", &lberBervType ) == LBER_ERROR) { lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls Error in reading control type from the PDU."); } if ( VmDirLogGetMask() & LDAP_DEBUG_ARGS) { VMDIR_LOG_INFO( LDAP_DEBUG_ARGS, " Request Control: %s", lberBervType.bv_val ); } if (VmDirAllocateMemory( sizeof( VDIR_LDAP_CONTROL), (PVOID *)control ) != 0) { retVal = lr->errCode = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: VmDirAllocateMemory failed"); } // type points into in-place ber and does NOT own its content (*control)->type = lberBervType.bv_val; (*control)->criticality = FALSE; tag = ber_peek_tag( op->ber, &len ); if (tag == LBER_BOOLEAN) { ber_int_t criticality; if (ber_scanf( op->ber, "b", &criticality) == LBER_ERROR) { lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: Error in reading control criticality from the PDU."); } if (criticality) { (*control)->criticality = TRUE; } tag = ber_peek_tag( op->ber, &len ); } if (tag == LBER_OCTETSTRING) { if (ber_scanf( op->ber, "m", &lberBervCtlValue) == LBER_ERROR) { lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: ber_scanf failed while parsing the control value."); } } // SJ-TBD: Make sure that the control appears only once in the request, and it is present only in a search // request if (VmDirStringCompareA( (*control)->type, LDAP_CONTROL_SYNC, TRUE ) == 0) { if (VmDirdGetRunMode() != VMDIR_RUNMODE_NORMAL) { // Why block out-bound replication when catching up during restore mode? // // Reason: Partners have high-water-mark (lastLocalUsn) corresponding to this replica that is being // restored. If out-bound replication is not blocked while restore/catching-up is going on, originating // or replicated updates (if this replica is the only partner) made between the current-local-usn and // high-water-marks, that partners remember, will not get replicated out (even if the invocationId // has been fixed/changed). retVal = lr->errCode = LDAP_UNWILLING_TO_PERFORM; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: Server not in normal mode, not allowing outward replication."); } if ((retVal = ParseSyncRequestControlVal( op, &lberBervCtlValue, &((*control)->value.syncReqCtrlVal), lr)) != LDAP_SUCCESS) { BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: ParseSyncRequestControlVal failed."); } op->syncReqCtrl = *control; } if (VmDirStringCompareA( (*control)->type, VDIR_LDAP_CONTROL_SHOW_DELETED_OBJECTS, TRUE ) == 0) { op->showDeletedObjectsCtrl = *control; } if (VmDirStringCompareA( (*control)->type, VDIR_LDAP_CONTROL_SHOW_MASTER_KEY, TRUE ) == 0) { op->showMasterKeyCtrl = *control; } if (VmDirStringCompareA((*control)->type, LDAP_CONTROL_CONSISTENT_WRITE, TRUE ) == 0) { op->strongConsistencyWriteCtrl = *control; } if (VmDirStringCompareA((*control)->type, VDIR_LDAP_CONTROL_MANAGEDDSAIT, TRUE ) == 0) { op->manageDsaITCtrl = *control; } if (VmDirStringCompareA( (*control)->type, LDAP_CONTROL_PAGEDRESULTS, TRUE ) == 0) { retVal = _ParsePagedResultControlVal( op, &lberBervCtlValue, &((*control)->value.pagedResultCtrlVal), lr); if (retVal != LDAP_SUCCESS) { BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: _ParsePagedResultControlVal failed."); } op->showPagedResultsCtrl = *control; } if (VmDirStringCompareA( (*control)->type, LDAP_CONTROL_CONDITIONAL_WRITE, TRUE ) == 0) { retVal = _ParseCondWriteControlVal( op, &lberBervCtlValue, &((*control)->value.condWriteCtrlVal), lr); if (retVal != LDAP_SUCCESS) { BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: _ParseConditionalWriteControlVal failed."); } op->pCondWriteCtrl = *control; } if (VmDirStringCompareA( (*control)->type, LDAP_APPEND_ENTRIES_CONTROL, TRUE ) == 0) { retVal = _ParseAppendEntriesControlVal( op, &lberBervCtlValue, &((*control)->value.appendEntriesCtrlVal), lr); if (retVal != LDAP_SUCCESS) { BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: _ParseAppendEntriesControlVal failed."); } op->appendEntriesCtrl = *control; } if (VmDirStringCompareA( (*control)->type, LDAP_REQUEST_VOTE_CONTROL, TRUE ) == 0) { retVal = _ParseRequestVoteControlVal( op, &lberBervCtlValue, &((*control)->value.requestVoteCtrlVal), lr); if (retVal != LDAP_SUCCESS) { BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: _ParseRequestVoteControlVal failed."); } op->requestVoteCtrl = *control; } if (VmDirStringCompareA( (*control)->type, VMDIR_LDAP_CONTROL_TXN_SPEC, TRUE ) == 0) { retVal = VmDirAllocateMemory(lberBervCtlValue.bv_len+1, (PVOID*)&((*control)->value.txnSpecCtrlVal).pszTxnId); BAIL_ON_VMDIR_ERROR(retVal); VmDirStringNCpyA(((*control)->value.txnSpecCtrlVal).pszTxnId, lberBervCtlValue.bv_len+1, lberBervCtlValue.bv_val, lberBervCtlValue.bv_len); op->txnSpecCtrl = *control; op->pBECtx->pszTxnId = (op->txnSpecCtrl->value.txnSpecCtrlVal).pszTxnId; } if ( ber_scanf( op->ber, "}") == LBER_ERROR ) // end of control { lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseRequestControls: ber_scanf failed while parsing the end of control"); } control = &((*control)->next); } retVal = LDAP_SUCCESS; } cleanup: VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseRequestControls: End." ); VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return retVal; error: DeleteControls(&(op->reqControls)); if (pszLocalErrorMsg) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, pszLocalErrorMsg); VMDIR_APPEND_ERROR_MSG(lr->pszErrMsg, pszLocalErrorMsg); } goto cleanup; }
int Ldap_get_ssa(BerElement *ber,struct berval *type, struct berval *value ) { ber_tag_t tag; ber_len_t len; char *last; int rc; struct berval desc, nvalue; if ( ber_scanf( ber, "{m" /*}*/, type ) == LBER_ERROR ) { return LBER_ERROR; } for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { if ( ber_scanf( ber, "m", value ) == LBER_ERROR ) { printf("| Filter-Decode Substring Error\n"); return LBER_ERROR; } if ( value->bv_val == NULL || value->bv_len == 0 ) { rc = LBER_ERROR; printf("| Filter-Decode Substring Error\n"); return rc; } #ifdef DEBUG printf("Debug: tag =%X\n"); #endif switch ( tag ) { case LDAP_SUBSTRING_INITIAL: #ifdef DEBUG printf("Filter- Initial:value-%s\n", value->bv_val); #endif rc=LDAP_SUBSTRING_INITIAL; break; case LDAP_SUBSTRING_ANY: #ifdef DEBUG printf("Filter- ANY:value-%s\n", value->bv_val); #endif rc=LDAP_SUBSTRING_ANY; break; case LDAP_SUBSTRING_FINAL: #ifdef DEBUG printf("Filter- FINAL:value-%s\n", value->bv_val); #endif rc=LDAP_SUBSTRING_FINAL; break; default: rc = LBER_ERROR; printf("| Filter-Decode Substring Error\n"); return rc; } } return rc /* LDAP_SUBSTR OPT : ANY INITIAL FINAL ERROR */ ; }
DWORD LwKrb5FindPac( krb5_context ctx, const krb5_ticket *pTgsTicket, const krb5_keyblock *serviceKey, OUT PVOID* ppchLogonInfo, OUT size_t* psLogonInfo ) { DWORD dwError = LW_ERROR_SUCCESS; //Do not free struct berval bv = {0}; struct berval contents = {0}; //Do not free krb5_authdata **ppCur = NULL; //Do not free associated buffer BerElement *ber = NULL; ber_tag_t tag = 0; ber_len_t len = 0; // Do not free char *cookie = NULL; int adType; ber_tag_t seqTag, context0Tag, context1Tag; char* pchLogonInfo = NULL; size_t sLogonInfo = 0; ber = ber_alloc_t(0); if (pTgsTicket && pTgsTicket->enc_part2) { ppCur = pTgsTicket->enc_part2->authorization_data; } while (ppCur && (*ppCur != NULL)) { if (ppCur[0]->ad_type == AD_IF_RELEVANT_TYPE) { // This auth data contains a DER encoded sequence of more // auth data. One of them could be a pac. bv.bv_len = ppCur[0]->length; bv.bv_val = (char *)ppCur[0]->contents; ber_init2(ber, &bv, 0); tag = ber_first_element(ber, &len, &cookie); while (tag != LBER_ERROR) { // Free does nothing if pointer is NULL ber_memfree(contents.bv_val); contents.bv_val = NULL; tag = ber_scanf(ber, "t{t[i]t[", &seqTag, &context0Tag, &adType, &context1Tag); if (tag == LBER_ERROR) { // This auth data is invalid. Skip it and try // the next one break; } tag = ber_scanf(ber, "o]}", &contents); if (tag == LBER_ERROR) { // This auth data is invalid. Skip it and try // the next one break; } if (adType == AD_WIN2K_PAC) { dwError = LwKrb5VerifyPac( ctx, pTgsTicket, &contents, serviceKey, &pchLogonInfo, &sLogonInfo); if (dwError == LW_ERROR_INVALID_MESSAGE) { dwError = LW_ERROR_SUCCESS; continue; } BAIL_ON_LW_ERROR(dwError); // Found a good PAC ! goto end_search; } //returns LBER_ERROR when there are no more elements left. tag = ber_next_element(ber, &len, cookie); } } ppCur++; } end_search: *ppchLogonInfo = pchLogonInfo; *psLogonInfo = sLogonInfo; cleanup: if (contents.bv_val != NULL) { ber_memfree(contents.bv_val); } if (ber != NULL) { ber_free(ber, 0); } return dwError; error: LW_SAFE_FREE_MEMORY(pchLogonInfo); *ppchLogonInfo = NULL; goto cleanup; }
int do_add( Connection *conn, Operation *op ) { BerElement *ber = op->o_ber; char *last; struct berval dn = { 0, NULL }; ber_len_t len; ber_tag_t tag; Entry *e; Backend *be; Modifications *modlist = NULL; Modifications **modtail = &modlist; Modifications tmp; const char *text; int rc = LDAP_SUCCESS; int manageDSAit; #ifdef LDAP_SLAPI Slapi_PBlock *pb = NULL; #endif /* LDAP_SLAPI */ #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", conn->c_connid,0,0 ); #else Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 ); #endif /* * Parse the add request. It looks like this: * * AddRequest := [APPLICATION 14] SEQUENCE { * name DistinguishedName, * attrs SEQUENCE OF SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } */ /* get the name */ if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "do_add: conn %d ber_scanf failed\n", conn->c_connid,0,0 ); #else Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 ); #endif send_ldap_disconnect( conn, op, LDAP_PROTOCOL_ERROR, "decoding error" ); return -1; } e = (Entry *) ch_calloc( 1, sizeof(Entry) ); rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "do_add: conn %d invalid dn (%s)\n", conn->c_connid, dn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_add: invalid dn (%s)\n", dn.bv_val, 0, 0 ); #endif send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, "invalid DN", NULL, NULL ); goto done; } #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ARGS, "do_add: conn %d dn (%s)\n", conn->c_connid, e->e_dn, 0 ); #else Debug( LDAP_DEBUG_ARGS, "do_add: dn (%s)\n", e->e_dn, 0, 0 ); #endif /* get the attrs */ for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { Modifications *mod; ber_tag_t rtag; rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_bvalues ); if ( rtag == LBER_ERROR ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "do_add: conn %d decoding error \n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_add: decoding error\n", 0, 0, 0 ); #endif send_ldap_disconnect( conn, op, LDAP_PROTOCOL_ERROR, "decoding error" ); rc = -1; goto done; } if ( tmp.sml_bvalues == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_add: conn %d no values for type %s\n", conn->c_connid, tmp.sml_type.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "no values for type %s\n", tmp.sml_type.bv_val, 0, 0 ); #endif send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "no values for attribute type", NULL, NULL ); goto done; } mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = LDAP_MOD_ADD; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; mod->sml_bvalues = tmp.sml_bvalues; *modtail = mod; modtail = &mod->sml_next; } if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "do_add: conn %d ber_scanf failed\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 ); #endif send_ldap_disconnect( conn, op, LDAP_PROTOCOL_ERROR, "decoding error" ); rc = -1; goto done; } if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_add: conn %d get_ctrls failed\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 ); #endif goto done; } if ( modlist == NULL ) { send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "no attributes provided", NULL, NULL ); goto done; } Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu ADD dn=\"%s\"\n", op->o_connid, op->o_opid, e->e_dn, 0, 0 ); if( e->e_nname.bv_len == 0 ) { /* protocolError may be a more appropriate error */ send_ldap_result( conn, op, rc = LDAP_ALREADY_EXISTS, NULL, "root DSE already exists", NULL, NULL ); goto done; } else if ( bvmatch( &e->e_nname, &global_schemandn ) ) { send_ldap_result( conn, op, rc = LDAP_ALREADY_EXISTS, NULL, "subschema subentry already exists", NULL, NULL ); goto done; } manageDSAit = get_manageDSAit( op ); /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ be = select_backend( &e->e_nname, manageDSAit, 0 ); if ( be == NULL ) { BerVarray ref = referral_rewrite( default_referral, NULL, &e->e_name, LDAP_SCOPE_DEFAULT ); if ( ref == NULL ) ref = default_referral; if ( ref != NULL ) { send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL, ref, NULL ); if ( ref != default_referral ) ber_bvarray_free( ref ); } else { send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, NULL, "referral missing", NULL, NULL ); } goto done; } /* check restrictions */ rc = backend_check_restrictions( be, conn, op, NULL, &text ) ; if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); goto done; } /* check for referrals */ rc = backend_check_referrals( be, conn, op, &e->e_name, &e->e_nname ); if ( rc != LDAP_SUCCESS ) { goto done; } #ifdef LDAP_SLAPI pb = initAddPlugin( be, conn, op, &dn, e, manageDSAit ); #endif /* LDAP_SLAPI */ /* * do the add if 1 && (2 || 3) * 1) there is an add function implemented in this backend; * 2) this backend is master for what it holds; * 3) it's a replica and the dn supplied is the updatedn. */ if ( be->be_add ) { /* do the update here */ int repl_user = be_isupdate(be, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER if ( !be->be_update_ndn.bv_len || repl_user ) #endif { int update = be->be_update_ndn.bv_len; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; rc = slap_mods_check( modlist, update, &text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); goto done; } if ( !repl_user ) { for( modtail = &modlist; *modtail != NULL; modtail = &(*modtail)->sml_next ) { assert( (*modtail)->sml_op == LDAP_MOD_ADD ); assert( (*modtail)->sml_desc != NULL ); } rc = slap_mods_opattrs( be, op, modlist, modtail, &text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); goto done; } } rc = slap_mods2entry( modlist, &e, repl_user, &text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); goto done; } #ifdef LDAP_SLAPI /* * Call the preoperation plugin here, because the entry * will actually contain something. */ rc = doPreAddPluginFNs( be, pb ); if ( rc != LDAP_SUCCESS ) { /* plugin will have sent result */ goto done; } #endif /* LDAP_SLAPI */ if ( (*be->be_add)( be, conn, op, e ) == 0 ) { #ifdef SLAPD_MULTIMASTER if ( !repl_user ) #endif { replog( be, op, &e->e_name, &e->e_nname, e ); } be_entry_release_w( be, conn, op, e ); e = NULL; } #ifndef SLAPD_MULTIMASTER } else { BerVarray defref; BerVarray ref; #ifdef LDAP_SLAPI /* * SLAPI_ADD_ENTRY will be empty, but this may be acceptable * on replicas (for now, it involves the minimum code intrusion). */ rc = doPreAddPluginFNs( be, pb ); if ( rc != LDAP_SUCCESS ) { /* plugin will have sent result */ goto done; } #endif /* LDAP_SLAPI */ defref = be->be_update_refs ? be->be_update_refs : default_referral; if ( defref ) { ref = referral_rewrite( defref, NULL, &e->e_name, LDAP_SCOPE_DEFAULT ); send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL, ref ? ref : defref, NULL ); if ( ref ) ber_bvarray_free( ref ); } else { send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, NULL, "referral missing", NULL, NULL ); } #endif /* SLAPD_MULTIMASTER */ } } else { #ifdef LDAP_SLAPI rc = doPreAddPluginFNs( be, pb ); if ( rc != LDAP_SUCCESS ) { /* plugin will have sent result */ goto done; } #endif #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_add: conn %d no backend support\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, " do_add: no backend support\n", 0, 0, 0 ); #endif send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, NULL, "operation not supported within namingContext", NULL, NULL ); } #ifdef LDAP_SLAPI doPostAddPluginFNs( be, pb ); #endif /* LDAP_SLAPI */ done: if( modlist != NULL ) { slap_mods_free( modlist ); } if( e != NULL ) { entry_free( e ); } return rc; }
/* * 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 ); }
int ldap_parse_derefresponse_control( LDAP *ld, LDAPControl *ctrl, LDAPDerefRes **drp2 ) { BerElement *ber; ber_tag_t tag; ber_len_t len; char *last; LDAPDerefRes *drhead = NULL, **drp; if ( ld == NULL || ctrl == NULL || drp2 == NULL ) { if ( ld ) ld->ld_errno = LDAP_PARAM_ERROR; return LDAP_PARAM_ERROR; } /* Create a BerElement from the berval returned in the control. */ ber = ber_init( &ctrl->ldctl_value ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } /* Extract the count and cookie from the control. */ drp = &drhead; for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { LDAPDerefRes *dr; LDAPDerefVal **dvp; char *last2; dr = LDAP_CALLOC( 1, sizeof(LDAPDerefRes) ); dvp = &dr->attrVals; tag = ber_scanf( ber, "{ao", &dr->derefAttr, &dr->derefVal ); if ( tag == LBER_ERROR ) { goto done; } tag = ber_peek_tag( ber, &len ); if ( tag == (LBER_CONSTRUCTED|LBER_CLASS_CONTEXT) ) { for ( tag = ber_first_element( ber, &len, &last2 ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last2 ) ) { LDAPDerefVal *dv; dv = LDAP_CALLOC( 1, sizeof(LDAPDerefVal) ); tag = ber_scanf( ber, "{a[W]}", &dv->type, &dv->vals ); if ( tag == LBER_ERROR ) { goto done; } *dvp = dv; dvp = &dv->next; } } tag = ber_scanf( ber, "}" ); if ( tag == LBER_ERROR ) { goto done; } *drp = dr; drp = &dr->next; } tag = 0; done:; ber_free( ber, 1 ); if ( tag == LBER_ERROR ) { if ( drhead != NULL ) { ldap_derefresponse_free( drhead ); } *drp2 = NULL; ld->ld_errno = LDAP_DECODING_ERROR; } else { *drp2 = drhead; ld->ld_errno = LDAP_SUCCESS; } return ld->ld_errno; }
/* * Extract the payload from a total update extended operation, * decode it, and produce a Slapi_Entry structure representing a new * entry to be added to the local database. */ static int decode_total_update_extop(Slapi_PBlock *pb, Slapi_Entry **ep) { BerElement *tmp_bere = NULL; Slapi_Entry *e = NULL; Slapi_Attr *attr = NULL; char *str = NULL; struct berval *extop_value = NULL; char *extop_oid = NULL; ber_len_t len; char *lasto; ber_tag_t tag; int rc; PRBool deleted; PR_ASSERT(NULL != pb); PR_ASSERT(NULL != ep); slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid); slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value); if ((NULL == extop_oid) || ((strcmp(extop_oid, REPL_NSDS50_REPLICATION_ENTRY_REQUEST_OID) != 0) && (strcmp(extop_oid, REPL_NSDS71_REPLICATION_ENTRY_REQUEST_OID) != 0)) || !BV_HAS_DATA(extop_value)) { /* Bogus */ goto loser; } if ((tmp_bere = ber_init(extop_value)) == NULL) { goto loser; } if ((e = slapi_entry_alloc()) == NULL) { goto loser; } if (ber_scanf(tmp_bere, "{") == LBER_ERROR) /* Begin outer sequence */ { goto loser; } /* The entry's uniqueid is first */ if (ber_scanf(tmp_bere, "a", &str) == LBER_ERROR) { goto loser; } slapi_entry_set_uniqueid(e, str); str = NULL; /* Slapi_Entry now owns the uniqueid */ /* The entry's DN is next */ if (ber_scanf(tmp_bere, "a", &str) == LBER_ERROR) { goto loser; } slapi_entry_set_dn(e, str); str = NULL; /* Slapi_Entry now owns the dn */ /* Get the attributes */ for ( tag = ber_first_element( tmp_bere, &len, &lasto ); tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET; tag = ber_next_element( tmp_bere, &len, lasto ) ) { if (my_ber_scanf_attr (tmp_bere, &attr, &deleted) != 0) { goto loser; } /* Add the attribute to the entry */ if (deleted) entry_add_deleted_attribute_wsi(e, attr); /* entry now owns attr */ else entry_add_present_attribute_wsi(e, attr); /* entry now owns attr */ attr = NULL; } if (ber_scanf(tmp_bere, "}") == LBER_ERROR) /* End sequence for this entry */ { goto loser; } /* Check for ldapsubentries and tombstone entries to set flags properly */ slapi_entry_attr_find(e, "objectclass", &attr); if (attr != NULL) { struct berval bv; bv.bv_val = "ldapsubentry"; bv.bv_len = strlen(bv.bv_val); if (slapi_attr_value_find(attr, &bv) == 0) { slapi_entry_set_flag(e, SLAPI_ENTRY_LDAPSUBENTRY); } bv.bv_val = SLAPI_ATTR_VALUE_TOMBSTONE; bv.bv_len = strlen(bv.bv_val); if (slapi_attr_value_find(attr, &bv) == 0) { slapi_entry_set_flag(e, SLAPI_ENTRY_FLAG_TOMBSTONE); } } /* If we get here, the entry is properly constructed. Return it. */ rc = 0; *ep = e; goto free_and_return; loser: rc = -1; /* slapi_ch_free accepts NULL pointer */ slapi_ch_free((void **)&str); if (attr != NULL) { slapi_attr_free (&attr); } if (NULL != e) { slapi_entry_free (e); } *ep = NULL; slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Error: could not decode extended " "operation containing entry for total update.\n"); free_and_return: if (NULL != tmp_bere) { ber_free(tmp_bere, 1); tmp_bere = NULL; } return rc; }
int ldap_parse_verify_credentials( LDAP *ld, LDAPMessage *res, int * code, char ** diagmsg, struct berval **cookie, struct berval **screds, LDAPControl ***ctrls) { int rc; char *retoid = NULL; struct berval *retdata = NULL; assert(ld != NULL); assert(LDAP_VALID(ld)); assert(res != NULL); assert(code != NULL); assert(diagmsg != NULL); rc = ldap_parse_extended_result(ld, res, &retoid, &retdata, 0); if( rc != LDAP_SUCCESS ) { ldap_perror(ld, "ldap_parse_verify_credentials"); return rc; } if (retdata) { ber_tag_t tag; ber_len_t len; ber_int_t i; BerElement * ber = ber_init(retdata); struct berval diagmsg_bv = BER_BVNULL; if (!ber) { rc = ld->ld_errno = LDAP_NO_MEMORY; goto done; } ber_scanf(ber, "{im" /*"}"*/, &i, &diagmsg_bv); if ( diagmsg != NULL ) { *diagmsg = LDAP_MALLOC( diagmsg_bv.bv_len + 1 ); AC_MEMCPY( *diagmsg, diagmsg_bv.bv_val, diagmsg_bv.bv_len ); (*diagmsg)[diagmsg_bv.bv_len] = '\0'; } *code = i; tag = ber_peek_tag(ber, &len); if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE) { ber_scanf(ber, "O", cookie); tag = ber_peek_tag(ber, &len); } if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_SCREDS) { ber_scanf(ber, "O", screds); tag = ber_peek_tag(ber, &len); } if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS) { int nctrls = 0; char * opaque; *ctrls = LDAP_MALLOC(1 * sizeof(LDAPControl *)); if (!*ctrls) { rc = LDAP_NO_MEMORY; goto done; } *ctrls[nctrls] = NULL; for(tag = ber_first_element(ber, &len, &opaque); tag != LBER_ERROR; tag = ber_next_element(ber, &len, opaque)) { LDAPControl *tctrl; LDAPControl **tctrls; tctrl = LDAP_CALLOC(1, sizeof(LDAPControl)); /* allocate pointer space for current controls (nctrls) * + this control + extra NULL */ tctrls = !tctrl ? NULL : LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *)); if (!tctrls) { /* allocation failure */ if (tctrl) LDAP_FREE(tctrl); ldap_controls_free(*ctrls); *ctrls = NULL; rc = LDAP_NO_MEMORY; goto done; } tctrls[nctrls++] = tctrl; tctrls[nctrls] = NULL; tag = ber_scanf(ber, "{a" /*"}"*/, &tctrl->ldctl_oid); if (tag == LBER_ERROR) { *ctrls = NULL; ldap_controls_free(tctrls); rc = LDAP_DECODING_ERROR; goto done; } tag = ber_peek_tag(ber, &len); if (tag == LBER_BOOLEAN) { ber_int_t crit; tag = ber_scanf(ber, "b", &crit); tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0; tag = ber_peek_tag(ber, &len); } if (tag == LBER_OCTETSTRING) { tag = ber_scanf( ber, "o", &tctrl->ldctl_value ); } else { BER_BVZERO( &tctrl->ldctl_value ); } *ctrls = tctrls; } } ber_free(ber, 1); } done: ber_bvfree(retdata); ber_memfree(retoid); return rc; }
/* This function is called to process operation that come over external connections */ void do_add( Slapi_PBlock *pb ) { Slapi_Operation *operation; BerElement *ber; char *last; ber_len_t len = LBER_ERROR; ber_tag_t tag; Slapi_Entry *e = NULL; int err; int rc; PRBool searchsubentry=PR_TRUE; slapi_log_err(SLAPI_LOG_TRACE, "do_add", "==>\n"); slapi_pblock_get( pb, SLAPI_OPERATION, &operation); ber = operation->o_ber; /* count the add request */ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps); /* * Parse the add request. It looks like this: * * AddRequest := [APPLICATION 14] SEQUENCE { * name DistinguishedName, * attrs SEQUENCE OF SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } */ /* get the name */ { char *rawdn = NULL; Slapi_DN mysdn; if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) { slapi_ch_free_string(&rawdn); slapi_log_err(SLAPI_LOG_ERR, "do_add", "ber_scanf failed (op=Add; params=DN)\n"); op_shared_log_error_access (pb, "ADD", "???", "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); return; } /* Check if we should be performing strict validation. */ if (config_get_dn_validate_strict()) { /* check that the dn is formatted correctly */ rc = slapi_dn_syntax_check(pb, rawdn, 1); if (rc) { /* syntax check failed */ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"", "strict: invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_ch_free_string(&rawdn); return; } } slapi_sdn_init_dn_passin(&mysdn, rawdn); if (rawdn && (strlen(rawdn) > 0) && (NULL == slapi_sdn_get_dn(&mysdn))) { /* normalization failed */ op_shared_log_error_access(pb, "ADD", rawdn, "invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_sdn_done(&mysdn); return; } e = slapi_entry_alloc(); /* Responsibility for DN is passed to the Entry. */ slapi_entry_init_ext(e, &mysdn, NULL); slapi_sdn_done(&mysdn); } slapi_log_err(SLAPI_LOG_ARGS, "do_add", "dn (%s)\n", (char *)slapi_entry_get_dn_const(e)); /* get the attrs */ for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET; tag = ber_next_element( ber, &len, last ) ) { char *type = NULL, *normtype = NULL; struct berval **vals = NULL; len = -1; /* reset - not used in loop */ if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); slapi_ch_free_string(&type); ber_bvecfree( vals ); goto free_and_return; } if ( vals == NULL ) { slapi_log_err(SLAPI_LOG_ERR, "do_add - no values for type %s\n", type, 0, 0 ); op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "null value"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL ); slapi_ch_free_string(&type); goto free_and_return; } normtype = slapi_attr_syntax_normalize(type); if ( !normtype || !*normtype ) { char ebuf[SLAPI_DSE_RETURNTEXT_SIZE]; rc = LDAP_INVALID_SYNTAX; slapi_create_errormsg(ebuf, sizeof(ebuf), "invalid type '%s'", type); op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), ebuf); send_ldap_result( pb, rc, NULL, ebuf, 0, NULL ); slapi_ch_free_string(&type); slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); goto free_and_return; } slapi_ch_free_string(&type); /* for now we just ignore attributes that client is not allowed to modify so not to break existing clients */ if (op_shared_is_allowed_attr (normtype, pb->pb_conn->c_isreplication_session)){ if (( rc = slapi_entry_add_values( e, normtype, vals )) != LDAP_SUCCESS ) { slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ADD dn=\"%s\", add values for type %s failed\n", pb->pb_conn->c_connid, operation->o_opid, slapi_entry_get_dn_const(e), normtype ); send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); goto free_and_return; } /* if this is uniqueid attribute, set uniqueid field of the entry */ if (strcasecmp (normtype, SLAPI_ATTR_UNIQUEID) == 0) { e->e_uniqueid = slapi_ch_strdup (vals[0]->bv_val); } if(searchsubentry) searchsubentry=check_oc_subentry(e,vals,normtype); } slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); } /* Ensure that created attributes are not used in the RDN. */ if (check_rdn_for_created_attrs(e)) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)), "invalid DN"); send_ldap_result( pb, LDAP_INVALID_DN_SYNTAX, NULL, "illegal attribute in RDN", 0, NULL ); goto free_and_return; } /* len, is ber_len_t, which is uint. Can't be -1. May be better to remove (len != 0) check */ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); goto free_and_return; } /* * in LDAPv3 there can be optional control extensions on * the end of an LDAPMessage. we need to read them in and * pass them to the backend. */ if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "failed to decode LDAP controls"); send_ldap_result( pb, err, NULL, NULL, 0, NULL ); goto free_and_return; } slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &operation->o_isroot ); slapi_pblock_set( pb, SLAPI_ADD_ENTRY, e ); if (pb->pb_conn->c_flags & CONN_FLAG_IMPORT) { /* this add is actually part of a bulk import -- punt */ handle_fast_add(pb, e); } else { op_shared_add ( pb ); } /* make sure that we don't free entry if it is successfully added */ e = NULL; free_and_return:; if (e) slapi_entry_free (e); }
int slap_parse_modlist( Operation *op, SlapReply *rs, BerElement *ber, req_modify_s *ms ) { ber_tag_t tag; ber_len_t len; char *last; Modifications **modtail = &ms->rs_mods.rs_modlist; ms->rs_mods.rs_modlist = NULL; ms->rs_increment = 0; rs->sr_err = LDAP_SUCCESS; /* collect modifications & save for later */ for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { ber_int_t mop; Modifications tmp, *mod; tmp.sml_nvalues = NULL; if ( ber_scanf( ber, "{e{m[W]}}", &mop, &tmp.sml_type, &tmp.sml_values ) == LBER_ERROR ) { rs->sr_text = "decoding modlist error"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = mop; mod->sml_flags = 0; mod->sml_type = tmp.sml_type; mod->sml_values = tmp.sml_values; mod->sml_nvalues = NULL; mod->sml_desc = NULL; mod->sml_next = NULL; *modtail = mod; switch( mop ) { case LDAP_MOD_ADD: if ( mod->sml_values == NULL ) { rs->sr_text = "modify/add operation requires values"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } /* fall through */ case LDAP_MOD_DELETE: case LDAP_MOD_REPLACE: break; case LDAP_MOD_INCREMENT: if( op->o_protocol >= LDAP_VERSION3 ) { ms->rs_increment++; if ( mod->sml_values == NULL ) { rs->sr_text = "modify/increment operation requires value"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } if ( !BER_BVISNULL( &mod->sml_values[ 1 ] ) ) { rs->sr_text = "modify/increment operation requires single value"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } break; } /* fall thru */ default: rs->sr_text = "unrecognized modify operation"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } modtail = &mod->sml_next; } *modtail = NULL; done: if ( rs->sr_err != LDAP_SUCCESS ) { slap_mods_free( ms->rs_mods.rs_modlist, 1 ); ms->rs_mods.rs_modlist = NULL; ms->rs_increment = 0; } return rs->sr_err; }
int ldap_parse_passwordpolicy_control( LDAP *ld, LDAPControl *ctrl, ber_int_t *expirep, ber_int_t *gracep, LDAPPasswordPolicyError *errorp ) { BerElement *ber; int exp = -1, grace = -1; ber_tag_t tag; ber_len_t berLen; char *last; int err = PP_noError; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( ctrl != NULL ); /* Create a BerElement from the berval returned in the control. */ ber = ber_init(&ctrl->ldctl_value); if (ber == NULL) { ld->ld_errno = LDAP_NO_MEMORY; return(ld->ld_errno); } tag = ber_peek_tag( ber, &berLen ); if (tag != LBER_SEQUENCE) goto exit; for( tag = ber_first_element( ber, &berLen, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &berLen, last ) ) { switch (tag) { case PPOLICY_WARNING: ber_skip_tag(ber, &berLen ); tag = ber_peek_tag( ber, &berLen ); switch( tag ) { case PPOLICY_EXPIRE: if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit; break; case PPOLICY_GRACE: if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit; break; default: goto exit; } break; case PPOLICY_ERROR: if (ber_get_enum( ber, &err ) == LBER_DEFAULT) goto exit; break; default: goto exit; } } ber_free(ber, 1); /* Return data to the caller for items that were requested. */ if (expirep) *expirep = exp; if (gracep) *gracep = grace; if (errorp) *errorp = err; ld->ld_errno = LDAP_SUCCESS; return(ld->ld_errno); exit: ber_free(ber, 1); ld->ld_errno = LDAP_DECODING_ERROR; return(ld->ld_errno); }
static int deref_parseCtrl ( Operation *op, SlapReply *rs, LDAPControl *ctrl ) { ber_tag_t tag; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; ber_len_t len; char *last; DerefSpec *dshead = NULL, **dsp = &dshead; BerVarray attributes = NULL; if ( op->o_deref != SLAP_CONTROL_NONE ) { rs->sr_text = "Dereference control specified multiple times"; return LDAP_PROTOCOL_ERROR; } if ( BER_BVISNULL( &ctrl->ldctl_value ) ) { rs->sr_text = "Dereference control value is absent"; return LDAP_PROTOCOL_ERROR; } if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) { rs->sr_text = "Dereference control value is empty"; return LDAP_PROTOCOL_ERROR; } ber_init2( ber, &ctrl->ldctl_value, 0 ); for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { struct berval derefAttr; DerefSpec *ds, *dstmp; const char *text; int rc; ber_len_t cnt = sizeof(struct berval); ber_len_t off = 0; if ( ber_scanf( ber, "{m{M}}", &derefAttr, &attributes, &cnt, off ) == LBER_ERROR || !cnt ) { rs->sr_text = "Dereference control: derefSpec decoding error"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } ds = (DerefSpec *)op->o_tmpcalloc( 1, sizeof(DerefSpec) + sizeof(AttributeDescription *)*(cnt + 1), op->o_tmpmemctx ); ds->ds_attributes = (AttributeDescription **)&ds[ 1 ]; ds->ds_nattrs = cnt; rc = slap_bv2ad( &derefAttr, &ds->ds_derefAttr, &text ); if ( rc != LDAP_SUCCESS ) { rs->sr_text = "Dereference control: derefAttr decoding error"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } for ( dstmp = dshead; dstmp && dstmp != ds; dstmp = dstmp->ds_next ) { if ( dstmp->ds_derefAttr == ds->ds_derefAttr ) { rs->sr_text = "Dereference control: derefAttr must be unique within control"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } } if ( !( ds->ds_derefAttr->ad_type->sat_syntax->ssyn_flags & SLAP_SYNTAX_DN )) { if ( ctrl->ldctl_iscritical ) { rs->sr_text = "Dereference control: derefAttr syntax not distinguishedName"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } rs->sr_err = LDAP_SUCCESS; goto justcleanup; } for ( cnt = 0; !BER_BVISNULL( &attributes[ cnt ] ); cnt++ ) { rc = slap_bv2ad( &attributes[ cnt ], &ds->ds_attributes[ cnt ], &text ); if ( rc != LDAP_SUCCESS ) { rs->sr_text = "Dereference control: attribute decoding error"; rs->sr_err = LDAP_PROTOCOL_ERROR; goto done; } } ber_memfree_x( attributes, op->o_tmpmemctx ); attributes = NULL; *dsp = ds; dsp = &ds->ds_next; } op->o_ctrlderef = (void *)dshead; op->o_deref = ctrl->ldctl_iscritical ? SLAP_CONTROL_CRITICAL : SLAP_CONTROL_NONCRITICAL; rs->sr_err = LDAP_SUCCESS; done:; if ( rs->sr_err != LDAP_SUCCESS ) { justcleanup:; for ( ; dshead; ) { DerefSpec *dsnext = dshead->ds_next; op->o_tmpfree( dshead, op->o_tmpmemctx ); dshead = dsnext; } } if ( attributes != NULL ) { ber_memfree_x( attributes, op->o_tmpmemctx ); } return rs->sr_err; }
int ldap_parse_passwordpolicy_control(LDAP UNUSED(*ld), LDAPControl *ctrl, ber_int_t *expirep, ber_int_t *gracep, LDAPPasswordPolicyError UNUSED(*errorp)) { BerElement *ber; ber_tag_t tag; ber_len_t berLen; char *last; #ifdef HAVE_BER_GET_ENUM int err = PP_noError; #endif /* HAVE_BER_GET_ENUM */ /* get a BerElement from the control */ ber = ber_init(&ctrl->ldctl_value); if (ber == NULL) return LDAP_LOCAL_ERROR; /* go over tags */ for(tag = ber_first_element(ber, &berLen, &last); tag != LBER_DEFAULT; tag = ber_next_element(ber, &berLen, last)) { switch (tag) { case PPOLICY_WARNING: ber_skip_tag(ber, &berLen); tag = ber_peek_tag(ber, &berLen); switch (tag) { case PPOLICY_EXPIRE: if (ber_get_int(ber, expirep) == LBER_DEFAULT) { ber_free(ber, 1); return LDAP_DECODING_ERROR; } break; case PPOLICY_GRACE: if (ber_get_int(ber, gracep) == LBER_DEFAULT) { ber_free(ber, 1); return LDAP_DECODING_ERROR; } break; default: ber_free(ber, 1); return LDAP_DECODING_ERROR; } break; #ifdef HAVE_BER_GET_ENUM case PPOLICY_ERROR: if (ber_get_enum(ber, &err) == LBER_DEFAULT) { ber_free(ber, 1); return LDAP_DECODING_ERROR; } break; #endif /* HAVE_BER_GET_ENUM */ default: ber_free(ber, 1); return LDAP_DECODING_ERROR; } } ber_free(ber, 1); return LDAP_SUCCESS; }