/* pw_string64 function taken from libraries/liblutil/passwd.c */ static int pw_string64( const struct berval *sc, const struct berval *hash, struct berval *b64, const struct berval *salt ) { int rc; struct berval string; size_t b64len; if( salt ) { /* need to base64 combined string */ string.bv_len = hash->bv_len + salt->bv_len; string.bv_val = ber_memalloc( string.bv_len + 1 ); if( string.bv_val == NULL ) { return LUTIL_PASSWD_ERR; } AC_MEMCPY( string.bv_val, hash->bv_val, hash->bv_len ); AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val, salt->bv_len ); string.bv_val[string.bv_len] = '\0'; } else { string = *hash; } b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1; b64->bv_len = b64len + sc->bv_len; b64->bv_val = ber_memalloc( b64->bv_len + 1 ); if( b64->bv_val == NULL ) { if( salt ) ber_memfree( string.bv_val ); return LUTIL_PASSWD_ERR; } AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len); rc = lutil_b64_ntop( (unsigned char *) string.bv_val, string.bv_len, &b64->bv_val[sc->bv_len], b64len ); if( salt ) ber_memfree( string.bv_val ); if( rc < 0 ) { return LUTIL_PASSWD_ERR; } /* recompute length */ b64->bv_len = sc->bv_len + rc; assert( strlen(b64->bv_val) == b64->bv_len ); return LUTIL_PASSWD_OK; }
static krb5_error_code LDAP_addmod(LDAPMod *** modlist, int modop, const char *attribute, const char *value) { int cMods, i = 0; krb5_error_code ret; ret = LDAP__setmod(modlist, modop, attribute, &cMods); if (ret) return ret; if (value != NULL) { char **bv; bv = (*modlist)[cMods]->mod_values; if (bv != NULL) { for (i = 0; bv[i] != NULL; i++) ; bv = ber_memrealloc(bv, (i + 2) * sizeof(*bv)); } else bv = ber_memalloc(2 * sizeof(*bv)); if (bv == NULL) return ENOMEM; (*modlist)[cMods]->mod_values = bv; bv[i] = ber_strdup(value); if (bv[i] == NULL) return ENOMEM; bv[i + 1] = NULL; } return 0; }
void * create_sasl_defaults(LDAP *ld, char *mech, char *realm, char *authcid, char *passwd, char *authzid) { lutilSASLdefaults *defaults; defaults = ber_memalloc(sizeof(lutilSASLdefaults)); if(defaults == NULL) return (void *)PyErr_NoMemory(); defaults->mech = mech ? ber_strdup(mech) : NULL; defaults->realm = realm ? ber_strdup(realm) : NULL; defaults->authcid = authcid ? ber_strdup(authcid) : NULL; defaults->passwd = passwd ? ber_strdup(passwd) : NULL; defaults->authzid = authzid ? ber_strdup(authzid) : NULL; if (defaults->mech == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech); } if (defaults->realm == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm); } if (defaults->authcid == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid); } if (defaults->authzid == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid); } defaults->resps = NULL; defaults->nresps = 0; return defaults; }
static RLDAP_BICTX *_rldap_sasl_setdefs(LDAP *ld, char *sasl_mech, char *sasl_realm, char *sasl_authc_id, char *passwd, char *sasl_authz_id) { RLDAP_BICTX *ctx; ctx = ber_memalloc(sizeof(RLDAP_BICTX)); ctx->mech = (sasl_mech) ? ber_strdup(sasl_mech) : NULL; ctx->realm = (sasl_realm) ? ber_strdup(sasl_realm) : NULL; ctx->authcid = (sasl_authc_id) ? ber_strdup(sasl_authc_id) : NULL; ctx->passwd = (passwd) ? ber_strdup(passwd) : NULL; ctx->authzid = (sasl_authz_id) ? ber_strdup(sasl_authz_id) : NULL; if (ctx->mech == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &ctx->mech); } if (ctx->realm == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &ctx->realm); } if (ctx->authcid == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &ctx->authcid); } if (ctx->authzid == NULL) { ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &ctx->authzid); } return ctx; }
char* chomp(char *s) { char* t = ber_memalloc(strlen(s)+1); strncpy (t,s,strlen(s)+1); if ( t[strlen(t)-1] == '\n' ) { t[strlen(t)-1] = '\0'; } return t; }
static krb5_error_code LDAP__setmod(LDAPMod *** modlist, int modop, const char *attribute, int *pIndex) { int cMods; if (*modlist == NULL) { *modlist = (LDAPMod **)ber_memcalloc(1, sizeof(LDAPMod *)); if (*modlist == NULL) return ENOMEM; } for (cMods = 0; (*modlist)[cMods] != NULL; cMods++) { if ((*modlist)[cMods]->mod_op == modop && strcasecmp((*modlist)[cMods]->mod_type, attribute) == 0) { break; } } *pIndex = cMods; if ((*modlist)[cMods] == NULL) { LDAPMod *mod; *modlist = (LDAPMod **)ber_memrealloc(*modlist, (cMods + 2) * sizeof(LDAPMod *)); if (*modlist == NULL) return ENOMEM; (*modlist)[cMods] = (LDAPMod *)ber_memalloc(sizeof(LDAPMod)); if ((*modlist)[cMods] == NULL) return ENOMEM; mod = (*modlist)[cMods]; mod->mod_op = modop; mod->mod_type = ber_strdup(attribute); if (mod->mod_type == NULL) { ber_memfree(mod); (*modlist)[cMods] = NULL; return ENOMEM; } if (modop & LDAP_MOD_BVALUES) { mod->mod_bvalues = NULL; } else { mod->mod_values = NULL; } (*modlist)[cMods + 1] = NULL; } return 0; }
static krb5_error_code LDAP_addmod_len(LDAPMod *** modlist, int modop, const char *attribute, unsigned char *value, size_t len) { krb5_error_code ret; int cMods, i = 0; ret = LDAP__setmod(modlist, modop | LDAP_MOD_BVALUES, attribute, &cMods); if (ret) return ret; if (value != NULL) { struct berval **bv; bv = (*modlist)[cMods]->mod_bvalues; if (bv != NULL) { for (i = 0; bv[i] != NULL; i++) ; bv = ber_memrealloc(bv, (i + 2) * sizeof(*bv)); } else bv = ber_memalloc(2 * sizeof(*bv)); if (bv == NULL) return ENOMEM; (*modlist)[cMods]->mod_bvalues = bv; bv[i] = ber_memalloc(sizeof(**bv));; if (bv[i] == NULL) return ENOMEM; bv[i]->bv_val = (void *)value; bv[i]->bv_len = len; bv[i + 1] = NULL; } return 0; }
static int realloc_error_message (char ** target, int curlen, int nextlen) { if (curlen < nextlen + MEMORY_MARGIN) { #if defined(DEBUG) syslog(LOG_WARNING, "check_password: Reallocating szErrStr from %d to %d", curlen, nextlen + MEMORY_MARGIN); #endif #if defined(LDEBUG) printf("check_password: Reallocating szErrStr from %d to %d\n", curlen, nextlen + MEMORY_MARGIN); #endif ber_memfree(*target); curlen = nextlen + MEMORY_MARGIN; *target = (char *) ber_memalloc(curlen); } return curlen; }
static int chk_sha512( const struct berval *scheme, /* Scheme of hashed reference password */ const struct berval *passwd, /* Hashed reference password to check against */ const struct berval *cred, /* user-supplied password to check */ const char **text ) { SHA512_CTX SHAcontext; unsigned char SHAdigest[SHA512_DIGEST_LENGTH]; int rc; unsigned char *orig_pass = NULL; size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); /* safety check */ if (decode_len < sizeof(SHAdigest)) { return LUTIL_PASSWD_ERR; } /* base64 un-encode password */ orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); if( rc != sizeof(SHAdigest) ) { ber_memfree(orig_pass); return LUTIL_PASSWD_ERR; } /* hash credentials with salt */ SHA512_Init(&SHAcontext); SHA512_Update(&SHAcontext, (const unsigned char *) cred->bv_val, cred->bv_len); SHA512_Final(SHAdigest, &SHAcontext); /* compare */ rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); #ifdef SLAPD_SHA2_DEBUG chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc); #endif ber_memfree(orig_pass); return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; }
/* ARGSUSED */ static int avl_buildlist( void* data, void* arg ) { static int slots; if ( avl_list == (void* *) 0 ) { avl_list = (void* *) ber_memalloc(AVL_GRABSIZE * sizeof(void*)); slots = AVL_GRABSIZE; avl_maxlist = 0; } else if ( avl_maxlist == slots ) { slots += AVL_GRABSIZE; avl_list = (void* *) ber_memrealloc( (char *) avl_list, (unsigned) slots * sizeof(void*)); } avl_list[ avl_maxlist++ ] = data; return( 0 ); }
static int chk_phk( const struct berval *magic, const struct berval *passwd, const struct berval *cred, const char **text) { unsigned char digest[LUTIL_MD5_BYTES]; unsigned char *orig_pass; int rc, n; struct berval salt; /* safety check */ n = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); if (n <= sizeof(digest)) return LUTIL_PASSWD_ERR; /* base64 un-encode password hash */ orig_pass = (unsigned char *) ber_memalloc((size_t) (n + 1)); if (orig_pass == NULL) return LUTIL_PASSWD_ERR; rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len); if (rc <= (int) sizeof(digest)) { ber_memfree(orig_pass); return LUTIL_PASSWD_ERR; } salt.bv_val = (char *) &orig_pass[sizeof(digest)]; salt.bv_len = rc - sizeof(digest); do_phk_hash(cred, magic, &salt, digest); if (text) *text = NULL; /* compare */ rc = memcmp((char *) orig_pass, (char *) digest, sizeof(digest)); ber_memfree(orig_pass); return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; }
static void chk_sha_debug( const struct berval *scheme, const struct berval *passwd, const struct berval *cred, const char *cred_hash, size_t cred_len, int cmp_rc) { int rc; struct berval cred_b64; cred_b64.bv_len = LUTIL_BASE64_ENCODE_LEN(cred_len) + 1; cred_b64.bv_val = ber_memalloc(cred_b64.bv_len + 1); if( cred_b64.bv_val == NULL ) { return; } rc = lutil_b64_ntop( (unsigned char *) cred_hash, cred_len, cred_b64.bv_val, cred_b64.bv_len ); if( rc < 0 ) { ber_memfree(cred_b64.bv_val); return; } fprintf(stderr, "Validating password\n"); fprintf(stderr, " Hash scheme:\t\t%s\n", scheme->bv_val); fprintf(stderr, " Password to validate: %s\n", cred->bv_val); fprintf(stderr, " Password hash:\t%s\n", cred_b64.bv_val); fprintf(stderr, " Stored password hash:\t%s\n", passwd->bv_val); fprintf(stderr, " Result:\t\t%s\n", cmp_rc ? "do not match" : "match"); ber_memfree(cred_b64.bv_val); }
/* Parse an LDIF control line of the form control: oid [true/false] [: value] or control: oid [true/false] [:: base64-value] or control: oid [true/false] [:< url] The control is added to the list of controls in *ppctrls. */ static int parse_ldif_control( struct berval *bval, LDAPControl ***ppctrls ) { char *oid = NULL; int criticality = 0; /* Default is false if not present */ int i, rc=0; char *s, *oidStart; LDAPControl *newctrl = NULL; LDAPControl **pctrls = NULL; struct berval type, bv; int freeval; if (ppctrls) pctrls = *ppctrls; /* OID should come first. Validate and extract it. */ s = bval->bv_val; if (*s == 0) return ( LDAP_PARAM_ERROR ); oidStart = s; while (isdigit((unsigned char)*s) || *s == '.') { s++; /* OID should be digits or . */ } if (s == oidStart) { return ( LDAP_PARAM_ERROR ); /* OID was not present */ } if (*s) { /* End of OID should be space or NULL */ if (!isspace((unsigned char)*s)) { return ( LDAP_PARAM_ERROR ); /* else OID contained invalid chars */ } *s++ = 0; /* Replace space with null to terminate */ } oid = ber_strdup(oidStart); if (oid == NULL) return ( LDAP_NO_MEMORY ); /* Optional Criticality field is next. */ while (*s && isspace((unsigned char)*s)) { s++; /* Skip white space before criticality */ } if (strncasecmp(s, "true", 4) == 0) { criticality = 1; s += 4; } else if (strncasecmp(s, "false", 5) == 0) { criticality = 0; s += 5; } /* Optional value field is next */ while (*s && isspace((unsigned char)*s)) { s++; /* Skip white space before value */ } if (*s) { if (*s != ':') { /* If value is present, must start with : */ rc = LDAP_PARAM_ERROR; goto cleanup; } /* Back up so value is in the form a: value a:: base64-value a:< url Then we can use ldif_parse_line2 to extract and decode the value */ s--; *s = 'a'; rc = ldif_parse_line2(s, &type, &bv, &freeval); if (rc < 0) { rc = LDAP_PARAM_ERROR; goto cleanup; } } /* Create a new LDAPControl structure. */ newctrl = (LDAPControl *)ber_memalloc(sizeof(LDAPControl)); if ( newctrl == NULL ) { rc = LDAP_NO_MEMORY; goto cleanup; } newctrl->ldctl_oid = oid; oid = NULL; newctrl->ldctl_iscritical = criticality; if ( freeval ) newctrl->ldctl_value = bv; else ber_dupbv( &newctrl->ldctl_value, &bv ); /* Add the new control to the passed-in list of controls. */ i = 0; if (pctrls) { while ( pctrls[i] ) { /* Count the # of controls passed in */ i++; } } /* Allocate 1 more slot for the new control and 1 for the NULL. */ pctrls = (LDAPControl **) ber_memrealloc(pctrls, (i+2)*(sizeof(LDAPControl *))); if (pctrls == NULL) { rc = LDAP_NO_MEMORY; goto cleanup; } pctrls[i] = newctrl; newctrl = NULL; pctrls[i+1] = NULL; *ppctrls = pctrls; cleanup: if (newctrl) { if (newctrl->ldctl_oid) ber_memfree(newctrl->ldctl_oid); if (newctrl->ldctl_value.bv_val) { ber_memfree(newctrl->ldctl_value.bv_val); } ber_memfree(newctrl); } if (oid) ber_memfree(oid); return( rc ); }
static int process_ldif_rec( char *rbuf, int linenum ) { char *line, *dn, *newrdn, *newsup; int rc, modop; int expect_modop, expect_sep; int deleteoldrdn; int new_entry, delete_entry, got_all; LDAPMod **pmods, *lm = NULL; int version; LDAPControl **pctrls; int i, j, k, lines, idn, nmods; struct berval *btype, *vals, **bvl, bv; char *freeval; unsigned char *mops = NULL; new_entry = ldapadd; rc = got_all = delete_entry = modop = expect_modop = 0; expect_sep = 0; version = 0; deleteoldrdn = 1; pmods = NULL; pctrls = NULL; dn = newrdn = newsup = NULL; lines = ldif_countlines( rbuf ); btype = ber_memcalloc( 1, (lines+1)*2*sizeof(struct berval)+lines ); if ( !btype ) return LDAP_NO_MEMORY; vals = btype+lines+1; freeval = (char *)(vals+lines+1); i = -1; while ( rc == 0 && ( line = ldif_getline( &rbuf )) != NULL ) { int freev; if ( *line == '\n' || *line == '\0' ) { break; } ++i; if ( line[0] == '-' && !line[1] ) { BER_BVZERO( btype+i ); freeval[i] = 0; continue; } if ( ( rc = ldif_parse_line2( line, btype+i, vals+i, &freev ) ) < 0 ) { fprintf( stderr, _("%s: invalid format (line %d) entry: \"%s\"\n"), prog, linenum+i, dn == NULL ? "" : dn ); rc = LDAP_PARAM_ERROR; break; } freeval[i] = freev; if ( dn == NULL ) { if ( linenum+i == 1 && BV_CASEMATCH( btype+i, &BV_VERSION )) { int v; if( vals[i].bv_len == 0 || lutil_atoi( &v, vals[i].bv_val) != 0 || v != 1 ) { fprintf( stderr, _("%s: invalid version %s, line %d (ignored)\n"), prog, vals[i].bv_val, linenum ); } version++; } else if ( BV_CASEMATCH( btype+i, &BV_DN )) { dn = vals[i].bv_val; idn = i; } /* skip all lines until we see "dn:" */ } } /* check to make sure there was a dn: line */ if ( !dn ) { rc = 0; goto leave; } lines = i+1; if( lines == 0 ) { rc = 0; goto leave; } if( version && lines == 1 ) { rc = 0; goto leave; } i = idn+1; /* Check for "control" tag after dn and before changetype. */ if ( BV_CASEMATCH( btype+i, &BV_CONTROL )) { /* Parse and add it to the list of controls */ rc = parse_ldif_control( vals+i, &pctrls ); if (rc != 0) { fprintf( stderr, _("%s: Error processing %s line, line %d: %s\n"), prog, BV_CONTROL.bv_val, linenum+i, ldap_err2string(rc) ); } i++; if ( i>= lines ) { short_input: fprintf( stderr, _("%s: Expecting more input after %s line, line %d\n"), prog, btype[i-1].bv_val, linenum+i ); rc = LDAP_PARAM_ERROR; goto leave; } } /* Check for changetype */ if ( BV_CASEMATCH( btype+i, &BV_CHANGETYPE )) { #ifdef LIBERAL_CHANGETYPE_MODOP /* trim trailing spaces (and log warning ...) */ int icnt; for ( icnt = vals[i].bv_len; --icnt > 0; ) { if ( !isspace( (unsigned char) vals[i].bv_val[icnt] ) ) { break; } } if ( ++icnt != vals[i].bv_len ) { fprintf( stderr, _("%s: illegal trailing space after" " \"%s: %s\" trimmed (line %d, entry \"%s\")\n"), prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn ); vals[i].bv_val[icnt] = '\0'; } #endif /* LIBERAL_CHANGETYPE_MODOP */ if ( BV_CASEMATCH( vals+i, &BV_MODIFYCT )) { new_entry = 0; expect_modop = 1; } else if ( BV_CASEMATCH( vals+i, &BV_ADDCT )) { new_entry = 1; modop = LDAP_MOD_ADD; } else if ( BV_CASEMATCH( vals+i, &BV_MODRDNCT ) || BV_CASEMATCH( vals+i, &BV_MODDNCT ) || BV_CASEMATCH( vals+i, &BV_RENAMECT )) { i++; if ( i >= lines ) goto short_input; if ( !BV_CASEMATCH( btype+i, &BV_NEWRDN )) { fprintf( stderr, _("%s: expecting \"%s:\" but saw" " \"%s:\" (line %d, entry \"%s\")\n"), prog, BV_NEWRDN.bv_val, btype[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } newrdn = vals[i].bv_val; i++; if ( i >= lines ) goto short_input; if ( !BV_CASEMATCH( btype+i, &BV_DELETEOLDRDN )) { fprintf( stderr, _("%s: expecting \"%s:\" but saw" " \"%s:\" (line %d, entry \"%s\")\n"), prog, BV_DELETEOLDRDN.bv_val, btype[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } deleteoldrdn = ( vals[i].bv_val[0] == '0' ) ? 0 : 1; i++; if ( i < lines ) { if ( !BV_CASEMATCH( btype+i, &BV_NEWSUP )) { fprintf( stderr, _("%s: expecting \"%s:\" but saw" " \"%s:\" (line %d, entry \"%s\")\n"), prog, BV_NEWSUP.bv_val, btype[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } newsup = vals[i].bv_val; i++; } got_all = 1; } else if ( BV_CASEMATCH( vals+i, &BV_DELETECT )) { got_all = delete_entry = 1; } else { fprintf( stderr, _("%s: unknown %s \"%s\" (line %d, entry \"%s\")\n"), prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } i++; } else if ( ldapadd ) { /* missing changetype => add */ new_entry = 1; modop = LDAP_MOD_ADD; } else { expect_modop = 1; /* missing changetype => modify */ } if ( got_all ) { if ( i < lines ) { fprintf( stderr, _("%s: extra lines at end (line %d, entry \"%s\")\n"), prog, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } goto doit; } nmods = lines - i; idn = i; if ( new_entry ) { int fv; /* Make sure all attributes with multiple values are contiguous */ for (; i<lines; i++) { for (j=i+1; j<lines; j++) { if ( BV_CASEMATCH( btype+i, btype+j )) { nmods--; /* out of order, move intervening attributes down */ if ( j != i+1 ) { bv = vals[j]; fv = freeval[j]; for (k=j; k>i; k--) { btype[k] = btype[k-1]; vals[k] = vals[k-1]; freeval[k] = freeval[k-1]; } k++; btype[k] = btype[i]; vals[k] = bv; freeval[k] = fv; } i++; } } } /* Allocate space for array of mods, array of pointers to mods, * and array of pointers to values, allowing for NULL terminators * for the pointer arrays... */ lm = ber_memalloc( nmods * sizeof(LDAPMod) + (nmods+1) * sizeof(LDAPMod*) + (lines + nmods - idn) * sizeof(struct berval *)); pmods = (LDAPMod **)(lm+nmods); bvl = (struct berval **)(pmods+nmods+1); j = 0; k = -1; BER_BVZERO(&bv); for (i=idn; i<lines; i++) { if ( BV_CASEMATCH( btype+i, &BV_DN )) { fprintf( stderr, _("%s: attributeDescription \"%s\":" " (possible missing newline" " after line %d, entry \"%s\"?)\n"), prog, btype[i].bv_val, linenum+i - 1, dn ); } if ( !BV_CASEMATCH( btype+i, &bv )) { bvl[k++] = NULL; bv = btype[i]; lm[j].mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES; lm[j].mod_type = bv.bv_val; lm[j].mod_bvalues = bvl+k; pmods[j] = lm+j; j++; } bvl[k++] = vals+i; } bvl[k] = NULL; pmods[j] = NULL; goto doit; } mops = ber_memalloc( lines+1 ); mops[lines] = M_SEP; mops[i-1] = M_SEP; for ( ; i<lines; i++ ) { if ( expect_modop ) { #ifdef LIBERAL_CHANGETYPE_MODOP /* trim trailing spaces (and log warning ...) */ int icnt; for ( icnt = vals[i].bv_len; --icnt > 0; ) { if ( !isspace( (unsigned char) vals[i].bv_val[icnt] ) ) break; } if ( ++icnt != vals[i].bv_len ) { fprintf( stderr, _("%s: illegal trailing space after" " \"%s: %s\" trimmed (line %d, entry \"%s\")\n"), prog, type, vals[i].bv_val, linenum+i, dn ); vals[i].bv_val[icnt] = '\0'; } #endif /* LIBERAL_CHANGETYPE_MODOP */ expect_modop = 0; expect_sep = 1; if ( BV_CASEMATCH( btype+i, &BV_MODOPADD )) { modop = LDAP_MOD_ADD; mops[i] = M_SEP; nmods--; } else if ( BV_CASEMATCH( btype+i, &BV_MODOPREPLACE )) { /* defer handling these since they might have no values. * Use the BVALUES flag to signal that these were * deferred. If values are provided later, this * flag will be switched off. */ modop = LDAP_MOD_REPLACE; mops[i] = modop | LDAP_MOD_BVALUES; btype[i] = vals[i]; } else if ( BV_CASEMATCH( btype+i, &BV_MODOPDELETE )) { modop = LDAP_MOD_DELETE; mops[i] = modop | LDAP_MOD_BVALUES; btype[i] = vals[i]; } else if ( BV_CASEMATCH( btype+i, &BV_MODOPINCREMENT )) { modop = LDAP_MOD_INCREMENT; mops[i] = M_SEP; nmods--; } else { /* no modify op: invalid LDIF */ fprintf( stderr, _("%s: modify operation type is missing at" " line %d, entry \"%s\"\n"), prog, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } bv = vals[i]; } else if ( expect_sep && BER_BVISEMPTY( btype+i )) { mops[i] = M_SEP; expect_sep = 0; expect_modop = 1; nmods--; } else { if ( !BV_CASEMATCH( btype+i, &bv )) { fprintf( stderr, _("%s: wrong attributeType at" " line %d, entry \"%s\"\n"), prog, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } mops[i] = modop; /* If prev op was deferred and matches this type, * clear the flag */ if ( (mops[i-1] & LDAP_MOD_BVALUES) && BV_CASEMATCH( btype+i, btype+i-1 )) { mops[i-1] = M_SEP; nmods--; } } } #if 0 /* we should faithfully encode the LDIF, not combine */ /* Make sure all modops with multiple values are contiguous */ for (i=idn; i<lines; i++) { if ( mops[i] == M_SEP ) continue; for (j=i+1; j<lines; j++) { if ( mops[j] == M_SEP || mops[i] != mops[j] ) continue; if ( BV_CASEMATCH( btype+i, btype+j )) { nmods--; /* out of order, move intervening attributes down */ if ( j != i+1 ) { int c; struct berval bv; char fv; c = mops[j]; bv = vals[j]; fv = freeval[j]; for (k=j; k>i; k--) { btype[k] = btype[k-1]; vals[k] = vals[k-1]; freeval[k] = freeval[k-1]; mops[k] = mops[k-1]; } k++; btype[k] = btype[i]; vals[k] = bv; freeval[k] = fv; mops[k] = c; } i++; } } } #endif /* Allocate space for array of mods, array of pointers to mods, * and array of pointers to values, allowing for NULL terminators * for the pointer arrays... */ lm = ber_memalloc( nmods * sizeof(LDAPMod) + (nmods+1) * sizeof(LDAPMod*) + (lines + nmods - idn) * sizeof(struct berval *)); pmods = (LDAPMod **)(lm+nmods); bvl = (struct berval **)(pmods+nmods+1); j = 0; k = -1; BER_BVZERO(&bv); mops[idn-1] = M_SEP; for (i=idn; i<lines; i++) { if ( mops[i] == M_SEP ) continue; if ( mops[i] != mops[i-1] || !BV_CASEMATCH( btype+i, &bv )) { bvl[k++] = NULL; bv = btype[i]; lm[j].mod_op = mops[i] | LDAP_MOD_BVALUES; lm[j].mod_type = bv.bv_val; if ( mops[i] & LDAP_MOD_BVALUES ) { lm[j].mod_bvalues = NULL; } else { lm[j].mod_bvalues = bvl+k; } pmods[j] = lm+j; j++; } bvl[k++] = vals+i; } bvl[k] = NULL; pmods[j] = NULL; doit: /* If default controls are set (as with -M option) and controls are specified in the LDIF file, we must add the default controls to the list of controls sent with the ldap operation. */ if ( rc == 0 ) { if (pctrls) { LDAPControl **defctrls = NULL; /* Default server controls */ LDAPControl **newctrls = NULL; ldap_get_option(ld, LDAP_OPT_SERVER_CONTROLS, &defctrls); if (defctrls) { int npc=0; /* Num of LDIF controls */ int ndefc=0; /* Num of default controls */ while (pctrls[npc]) npc++; /* Count LDIF controls */ while (defctrls[ndefc]) ndefc++; /* Count default controls */ newctrls = ber_memrealloc(pctrls, (npc+ndefc+1)*sizeof(LDAPControl*)); if (newctrls == NULL) { rc = LDAP_NO_MEMORY; } else { int i; pctrls = newctrls; for (i=npc; i<npc+ndefc; i++) { pctrls[i] = ldap_control_dup(defctrls[i-npc]); if (pctrls[i] == NULL) { rc = LDAP_NO_MEMORY; break; } } pctrls[npc+ndefc] = NULL; } ldap_controls_free(defctrls); /* Must be freed by library */ } } } if ( rc == 0 ) { if ( delete_entry ) { rc = dodelete( dn, pctrls ); } else if ( newrdn != NULL ) { rc = dorename( dn, newrdn, newsup, deleteoldrdn, pctrls ); } else { rc = domodify( dn, pmods, pctrls, new_entry ); } if ( rc == LDAP_SUCCESS ) { rc = 0; } } leave: if (pctrls != NULL) { ldap_controls_free( pctrls ); } if ( lm != NULL ) { ber_memfree( lm ); } if ( mops != NULL ) { ber_memfree( mops ); } for (i=lines-1; i>=0; i--) if ( freeval[i] ) ber_memfree( vals[i].bv_val ); ber_memfree( btype ); return( rc ); }
int main( int argc, char **argv ) { char *rbuf = NULL, *rejbuf = NULL; FILE *rejfp; struct LDIFFP *ldiffp, ldifdummy = {0}; char *matched_msg, *error_msg; int rc, retval; int len; int i = 0; int lineno, nextline = 0, lmax = 0; LDAPControl c[1]; prog = lutil_progname( "ldapmodify", argc, argv ); /* strncmp instead of strcmp since NT binaries carry .exe extension */ ldapadd = ( strncasecmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 ); tool_init( ldapadd ? TOOL_ADD : TOOL_MODIFY ); tool_args( argc, argv ); if ( argc != optind ) usage(); if ( rejfile != NULL ) { if (( rejfp = fopen( rejfile, "w" )) == NULL ) { perror( rejfile ); return( EXIT_FAILURE ); } } else { rejfp = NULL; } if ( infile != NULL ) { if (( ldiffp = ldif_open( infile, "r" )) == NULL ) { perror( infile ); return( EXIT_FAILURE ); } } else { ldifdummy.fp = stdin; ldiffp = &ldifdummy; } if ( debug ) ldif_debug = debug; ld = tool_conn_setup( dont, 0 ); if ( !dont ) { if ( pw_file || want_bindpw ) { if ( pw_file ) { rc = lutil_get_filed_password( pw_file, &passwd ); if( rc ) return EXIT_FAILURE; } else { passwd.bv_val = getpassphrase( _("Enter LDAP Password: "******"ldap_txn_start_s", rc, NULL, NULL, NULL, NULL ); if( txn > 1 ) return EXIT_FAILURE; txn = 0; } } #endif if ( 0 #ifdef LDAP_X_TXN || txn #endif ) { #ifdef LDAP_X_TXN if( txn ) { c[i].ldctl_oid = LDAP_CONTROL_X_TXN_SPEC; c[i].ldctl_value = *txn_id; c[i].ldctl_iscritical = 1; i++; } #endif } tool_server_controls( ld, c, i ); rc = 0; retval = 0; lineno = 1; while (( rc == 0 || contoper ) && ldif_read_record( ldiffp, &nextline, &rbuf, &lmax )) { if ( rejfp ) { len = strlen( rbuf ); if (( rejbuf = (char *)ber_memalloc( len+1 )) == NULL ) { perror( "malloc" ); exit( EXIT_FAILURE ); } memcpy( rejbuf, rbuf, len+1 ); } rc = process_ldif_rec( rbuf, lineno ); lineno = nextline+1; if ( rc ) retval = rc; if ( rc && rejfp ) { fprintf(rejfp, _("# Error: %s (%d)"), ldap_err2string(rc), rc); matched_msg = NULL; ldap_get_option(ld, LDAP_OPT_MATCHED_DN, &matched_msg); if ( matched_msg != NULL ) { if ( *matched_msg != '\0' ) { fprintf( rejfp, _(", matched DN: %s"), matched_msg ); } ldap_memfree( matched_msg ); } error_msg = NULL; ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &error_msg); if ( error_msg != NULL ) { if ( *error_msg != '\0' ) { fprintf( rejfp, _(", additional info: %s"), error_msg ); } ldap_memfree( error_msg ); } fprintf( rejfp, "\n%s\n", rejbuf ); } if (rejfp) ber_memfree( rejbuf ); } ber_memfree( rbuf ); #ifdef LDAP_X_TXN if( retval == 0 && txn ) { rc = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, NULL ); if ( rc != LDAP_OPT_SUCCESS ) { fprintf( stderr, "Could not unset controls for ldap_txn_end\n"); } /* create transaction */ rc = ldap_txn_end_s( ld, !txnabort, txn_id, NULL, NULL, NULL ); if( rc != LDAP_SUCCESS ) { tool_perror( "ldap_txn_end_s", rc, NULL, NULL, NULL, NULL ); retval = rc; } } #endif if ( !dont ) { tool_unbind( ld ); } if ( rejfp != NULL ) { fclose( rejfp ); } tool_destroy(); return( retval ); }
/* * avl_insert -- insert a node containing data data into the avl tree * with root root. fcmp is a function to call to compare the data portion * of two nodes. it should take two arguments and return <, >, or == 0, * depending on whether its first argument is <, >, or == its second * argument (like strcmp, e.g.). fdup is a function to call when a duplicate * node is inserted. it should return 0, or -1 and its return value * will be the return value from avl_insert in the case of a duplicate node. * the function will be called with the original node's data as its first * argument and with the incoming duplicate node's data as its second * argument. this could be used, for example, to keep a count with each * node. * * NOTE: this routine may malloc memory */ int avl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup ) { Avlnode *t, *p, *s, *q, *r; int a, cmp, ncmp; if ( *root == NULL ) { if (( r = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) { return( -1 ); } r->avl_link[0] = r->avl_link[1] = NULL; r->avl_data = data; r->avl_bf = EH; *root = r; return( 0 ); } t = NULL; s = p = *root; /* find insertion point */ while (1) { cmp = fcmp( data, p->avl_data ); if ( cmp == 0 ) return (*fdup)( p->avl_data, data ); cmp = (cmp > 0); q = p->avl_link[cmp]; if (q == NULL) { /* insert */ if (( q = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) { return( -1 ); } q->avl_link[0] = q->avl_link[1] = NULL; q->avl_data = data; q->avl_bf = EH; p->avl_link[cmp] = q; break; } else if ( q->avl_bf ) { t = p; s = q; } p = q; } /* adjust balance factors */ cmp = fcmp( data, s->avl_data ) > 0; r = p = s->avl_link[cmp]; a = avl_bfs[cmp]; while ( p != q ) { cmp = fcmp( data, p->avl_data ) > 0; p->avl_bf = avl_bfs[cmp]; p = p->avl_link[cmp]; } /* checks and balances */ if ( s->avl_bf == EH ) { s->avl_bf = a; return 0; } else if ( s->avl_bf == -a ) { s->avl_bf = EH; return 0; } else if ( s->avl_bf == a ) { cmp = (a > 0); ncmp = !cmp; if ( r->avl_bf == a ) { /* single rotation */ p = r; s->avl_link[cmp] = r->avl_link[ncmp]; r->avl_link[ncmp] = s; s->avl_bf = 0; r->avl_bf = 0; } else if ( r->avl_bf == -a ) { /* double rotation */ p = r->avl_link[ncmp]; r->avl_link[ncmp] = p->avl_link[cmp]; p->avl_link[cmp] = r; s->avl_link[cmp] = p->avl_link[ncmp]; p->avl_link[ncmp] = s; if ( p->avl_bf == a ) { s->avl_bf = -a; r->avl_bf = 0; } else if ( p->avl_bf == -a ) { s->avl_bf = 0; r->avl_bf = a; } else { s->avl_bf = 0; r->avl_bf = 0; } p->avl_bf = 0; } /* Update parent */ if ( t == NULL ) *root = p; else if ( s == t->avl_right ) t->avl_right = p; else t->avl_left = p; } return 0; }
static int aa_operational( Operation *op, SlapReply *rs ) { Attribute *a, **ap; AccessControlState acl_state = ACL_STATE_INIT; struct berval *v; AttributeType **atp = NULL; ObjectClass **ocp = NULL; #define GOT_NONE (0x0U) #define GOT_C (0x1U) #define GOT_CE (0x2U) #define GOT_A (0x4U) #define GOT_AE (0x8U) #define GOT_ALL (GOT_C|GOT_CE|GOT_A|GOT_AE) int got = GOT_NONE; /* only add if requested */ if ( SLAP_OPATTRS( rs->sr_attr_flags ) ) { got = GOT_ALL; } else { if ( ad_inlist( ad_allowedChildClasses, rs->sr_attrs ) ) { got |= GOT_C; } if ( ad_inlist( ad_allowedChildClassesEffective, rs->sr_attrs ) ) { got |= GOT_CE; } if ( ad_inlist( ad_allowedAttributes, rs->sr_attrs ) ) { got |= GOT_A; } if ( ad_inlist( ad_allowedAttributesEffective, rs->sr_attrs ) ) { got |= GOT_AE; } } if ( got == GOT_NONE ) { return SLAP_CB_CONTINUE; } /* shouldn't be called without an entry; please check */ assert( rs->sr_entry != NULL ); for ( ap = &rs->sr_operational_attrs; *ap != NULL; ap = &(*ap)->a_next ) /* go to last */ ; /* see caveats; this is not guaranteed for all backends */ a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_objectClass ); if ( a == NULL ) { goto do_oc; } /* if client has no access to objectClass attribute; don't compute */ if ( !access_allowed( op, rs->sr_entry, slap_schema.si_ad_objectClass, NULL, ACL_READ, &acl_state ) ) { return SLAP_CB_CONTINUE; } for ( v = a->a_nvals; !BER_BVISNULL( v ); v++ ) { ObjectClass *oc = oc_bvfind( v ); assert( oc != NULL ); /* if client has no access to specific value, don't compute */ if ( !access_allowed( op, rs->sr_entry, slap_schema.si_ad_objectClass, &oc->soc_cname, ACL_READ, &acl_state ) ) { continue; } aa_add_oc( oc, &ocp, &atp ); if ( oc->soc_sups ) { int i; for ( i = 0; oc->soc_sups[ i ] != NULL; i++ ) { aa_add_oc( oc->soc_sups[ i ], &ocp, &atp ); } } } ch_free( ocp ); if ( atp != NULL ) { BerVarray bv_allowed = NULL, bv_effective = NULL; int i, ja = 0, je = 0; for ( i = 0; atp[ i ] != NULL; i++ ) /* just count */ ; if ( got & GOT_A ) { bv_allowed = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) ); } if ( got & GOT_AE ) { bv_effective = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) ); } for ( i = 0, ja = 0, je = 0; atp[ i ] != NULL; i++ ) { if ( got & GOT_A ) { ber_dupbv( &bv_allowed[ ja ], &atp[ i ]->sat_cname ); ja++; } if ( got & GOT_AE ) { AttributeDescription *ad = NULL; const char *text = NULL; if ( slap_bv2ad( &atp[ i ]->sat_cname, &ad, &text ) ) { /* log? */ continue; } if ( access_allowed( op, rs->sr_entry, ad, NULL, ACL_WRITE, NULL ) ) { ber_dupbv( &bv_effective[ je ], &atp[ i ]->sat_cname ); je++; } } } ch_free( atp ); if ( ( got & GOT_A ) && ja > 0 ) { BER_BVZERO( &bv_allowed[ ja ] ); *ap = attr_alloc( ad_allowedAttributes ); (*ap)->a_vals = bv_allowed; (*ap)->a_nvals = bv_allowed; (*ap)->a_numvals = ja; ap = &(*ap)->a_next; } if ( ( got & GOT_AE ) && je > 0 ) { BER_BVZERO( &bv_effective[ je ] ); *ap = attr_alloc( ad_allowedAttributesEffective ); (*ap)->a_vals = bv_effective; (*ap)->a_nvals = bv_effective; (*ap)->a_numvals = je; ap = &(*ap)->a_next; } *ap = NULL; } do_oc:; if ( ( got & GOT_C ) || ( got & GOT_CE ) ) { BerVarray bv_allowed = NULL, bv_effective = NULL; int i, ja = 0, je = 0; ObjectClass *oc; for ( oc_start( &oc ); oc != NULL; oc_next( &oc ) ) { /* we can only add AUXILIARY objectClasses */ if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) { continue; } i++; } if ( got & GOT_C ) { bv_allowed = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) ); } if ( got & GOT_CE ) { bv_effective = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) ); } for ( oc_start( &oc ); oc != NULL; oc_next( &oc ) ) { /* we can only add AUXILIARY objectClasses */ if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) { continue; } if ( got & GOT_C ) { ber_dupbv( &bv_allowed[ ja ], &oc->soc_cname ); ja++; } if ( got & GOT_CE ) { if ( !access_allowed( op, rs->sr_entry, slap_schema.si_ad_objectClass, &oc->soc_cname, ACL_WRITE, NULL ) ) { goto done_ce; } if ( oc->soc_required ) { for ( i = 0; oc->soc_required[ i ] != NULL; i++ ) { AttributeDescription *ad = NULL; const char *text = NULL; if ( slap_bv2ad( &oc->soc_required[ i ]->sat_cname, &ad, &text ) ) { /* log? */ continue; } if ( !access_allowed( op, rs->sr_entry, ad, NULL, ACL_WRITE, NULL ) ) { goto done_ce; } } } ber_dupbv( &bv_effective[ je ], &oc->soc_cname ); je++; } done_ce:; } if ( ( got & GOT_C ) && ja > 0 ) { BER_BVZERO( &bv_allowed[ ja ] ); *ap = attr_alloc( ad_allowedChildClasses ); (*ap)->a_vals = bv_allowed; (*ap)->a_nvals = bv_allowed; (*ap)->a_numvals = ja; ap = &(*ap)->a_next; } if ( ( got & GOT_CE ) && je > 0 ) { BER_BVZERO( &bv_effective[ je ] ); *ap = attr_alloc( ad_allowedChildClassesEffective ); (*ap)->a_vals = bv_effective; (*ap)->a_nvals = bv_effective; (*ap)->a_numvals = je; ap = &(*ap)->a_next; } *ap = NULL; } return SLAP_CB_CONTINUE; }
/* Get a password from a file. */ int lutil_get_filed_password( const char *filename, struct berval *passwd ) { size_t nread, nleft, nr; FILE *f = fopen( filename, "r" ); if( f == NULL ) { perror( filename ); return -1; } passwd->bv_val = NULL; passwd->bv_len = 4096; #ifdef HAVE_FSTAT { struct stat sb; if ( fstat( fileno( f ), &sb ) == 0 ) { if( sb.st_mode & 006 ) { fprintf( stderr, _("Warning: Password file %s" " is publicly readable/writeable\n"), filename ); } if ( sb.st_size ) passwd->bv_len = sb.st_size; } } #endif /* HAVE_FSTAT */ passwd->bv_val = (char *) ber_memalloc( passwd->bv_len + 1 ); if( passwd->bv_val == NULL ) { perror( filename ); return -1; } nread = 0; nleft = passwd->bv_len; do { if( nleft == 0 ) { /* double the buffer size */ char *p = (char *) ber_memrealloc( passwd->bv_val, 2 * passwd->bv_len + 1 ); if( p == NULL ) { ber_memfree( passwd->bv_val ); passwd->bv_val = NULL; passwd->bv_len = 0; return -1; } nleft = passwd->bv_len; passwd->bv_len *= 2; passwd->bv_val = p; } nr = fread( &passwd->bv_val[nread], 1, nleft, f ); if( nr < nleft && ferror( f ) ) { ber_memfree( passwd->bv_val ); passwd->bv_val = NULL; passwd->bv_len = 0; return -1; } nread += nr; nleft -= nr; } while ( !feof(f) ); passwd->bv_len = nread; passwd->bv_val[nread] = '\0'; fclose( f ); return 0; }
int check_password (char *pPasswd, char **ppErrStr, Entry *pEntry) { char *szErrStr = (char *) ber_memalloc(MEM_INIT_SZ); int mem_len = MEM_INIT_SZ; int nLen; int nLower = 0; int nUpper = 0; int nDigit = 0; int nPunct = 0; int min_lower = 0; int min_upper = 0; int min_digit = 0; int min_punct = 0; int max_consecutive_per_class = 0; int nQuality = 0; int i; /* Set a sensible default to keep original behaviour. */ int min_quality = DEFAULT_QUALITY; int use_cracklib = DEFAULT_CRACKLIB; nLen = strlen (pPasswd); if (read_config_file() == -1) { syslog(LOG_ERR, "Warning: Could not read values from config file %s. Using defaults.", CONFIG_FILE); #if defined(LDEBUG) printf("Error: Could not read values from config file %s\n", CONFIG_FILE); #endif } #if defined(LDEBUG) || defined(DEBUG) print_config_entries(); #endif min_quality = get_config_entry_int("min_points"); use_cracklib = get_config_entry_int("use_cracklib"); min_upper = get_config_entry_int("min_upper"); min_lower = get_config_entry_int("min_lower"); min_digit = get_config_entry_int("min_digit"); min_punct = get_config_entry_int("min_punct"); max_consecutive_per_class = get_config_entry_int("max_consecutive_per_class"); /* Check Max Consecutive Per Class first since this has the most likelihood * of being wrong. */ if ( max_consecutive_per_class != 0 ) { char prev_type = '\0'; char this_type = ' '; i = 0; int consec_chars = 0; for ( i = 0; i < nLen; i++ ) { if ( islower(pPasswd[i]) ) { this_type = 'l'; } else if ( isupper(pPasswd[i]) ) { this_type = 'u'; } else if ( isdigit(pPasswd[i]) ) { this_type = 'd'; } else if ( ispunct(pPasswd[i]) ) { this_type = 'p'; } else { this_type = ' '; } if (this_type == prev_type) { ++consec_chars; } else if (i > 0) { consec_chars = 0; } prev_type = this_type; if ( consec_chars >= max_consecutive_per_class ) { mem_len = realloc_error_message(&szErrStr, mem_len, strlen(CONSEC_FAIL_SZ) + strlen(pEntry->e_name.bv_val)); sprintf (szErrStr, CONSEC_FAIL_SZ, pEntry->e_name.bv_val); goto fail; } } } /** The password must have at least min_quality strength points with one * point for the first occurrance of a lower, upper, digit and * punctuation character */ for ( i = 0; i < nLen; i++ ) { //if ( nQuality >= min_quality ) break; if ( islower (pPasswd[i]) ) { min_lower--; if ( !nLower && (min_lower < 1)) { nLower = 1; nQuality++; #if defined(DEBUG) syslog(LOG_NOTICE, "check_password: Found lower character - quality raise %d", nQuality); #endif #if defined(LDEBUG) printf("check_password: Found lower character - quality raise %d\n", nQuality); #endif } continue; } if ( isupper (pPasswd[i]) ) { min_upper--; if ( !nUpper && (min_upper < 1)) { nUpper = 1; nQuality++; #if defined(DEBUG) syslog(LOG_NOTICE, "check_password: Found upper character - quality raise %d", nQuality); #endif #if defined(LDEBUG) printf("check_password: Found upper character - quality raise %d\n", nQuality); #endif } continue; } if ( isdigit (pPasswd[i]) ) { min_digit--; if ( !nDigit && (min_digit < 1)) { nDigit = 1; nQuality++; #if defined(DEBUG) syslog(LOG_NOTICE, "check_password: Found digit character - quality raise %d", nQuality); #endif #if defined(LDEBUG) printf("check_password: Found digit character - quality raise %d\n", nQuality); #endif } continue; } if ( ispunct (pPasswd[i]) ) { min_punct--; if ( !nPunct && (min_punct < 1)) { nPunct = 1; nQuality++; #if defined(DEBUG) syslog(LOG_NOTICE, "check_password: Found punctuation character - quality raise %d", nQuality); #endif #if defined(LDEBUG) printf("check_password: Found punctuation character - quality raise %d\n", nQuality); #endif } continue; } } /* * If you have a required field, then it should be required in the strength * checks. */ if ( (min_lower > 0 ) || (min_upper > 0 ) || (min_digit > 0 ) || (min_punct > 0 ) || (nQuality < min_quality) ) { mem_len = realloc_error_message(&szErrStr, mem_len, strlen(PASSWORD_QUALITY_SZ) + strlen(pEntry->e_name.bv_val) + 2); sprintf (szErrStr, PASSWORD_QUALITY_SZ, pEntry->e_name.bv_val, nQuality, min_quality); goto fail; } #ifdef HAVE_CRACKLIB /** Check password with cracklib */ if ( use_cracklib > 0 ) { int j = 0; FILE* fp; char filename[FILENAME_MAXLEN]; char const* ext[] = { "hwm", "pwd", "pwi" }; int nErr = 0; /** * Silently fail when cracklib wordlist is not found */ for ( j = 0; j < 3; j++ ) { snprintf (filename, FILENAME_MAXLEN - 1, "%s.%s", \ CRACKLIB_DICTPATH, ext[j]); if (( fp = fopen ( filename, "r")) == NULL ) { nErr = 1; break; } else { fclose (fp); } } char *r; if ( nErr == 0) { r = (char *) FascistCheck (pPasswd, CRACKLIB_DICTPATH); if ( r != NULL ) { mem_len = realloc_error_message(&szErrStr, mem_len, strlen(BAD_PASSWORD_SZ) + strlen(pEntry->e_name.bv_val) + strlen(r)); sprintf (szErrStr, BAD_PASSWORD_SZ, pEntry->e_name.bv_val, r); goto fail; } } } else { #if defined(DEBUG) syslog(LOG_NOTICE, "check_password: Cracklib verification disabled by configuration"); #endif #if defined(LDEBUG) printf("check_password: Cracklib verification disabled by configuration"); #endif } #endif #if defined(LDEBUG) || defined(DEBUG) print_config_entries(); #endif dealloc_config_entries(); *ppErrStr = strdup (""); ber_memfree(szErrStr); return (LDAP_SUCCESS); fail: dealloc_config_entries(); *ppErrStr = strdup (szErrStr); ber_memfree(szErrStr); return (EXIT_FAILURE); }
static int slap_open_listener( const char* url, int *listeners, int *cur ) { int num, tmp, rc; Listener l; Listener *li; LDAPURLDesc *lud; unsigned short port; int err, addrlen = 0; struct sockaddr **sal, **psal; int socktype = SOCK_STREAM; /* default to COTS */ #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD) /* * use safe defaults */ int crit = 1; #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */ rc = ldap_url_parse( url, &lud ); if( rc != LDAP_URL_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, "slap_open_listener: listen URL \"%s\" parse error %d\n", url, rc , 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon: listen URL \"%s\" parse error=%d\n", url, rc, 0 ); #endif return rc; } l.sl_url.bv_val = NULL; l.sl_is_mute = 0; #ifndef HAVE_TLS if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_open_listener: TLS is not supported (%s)\n", url, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon: TLS not supported (%s)\n", url, 0, 0 ); #endif ldap_free_urldesc( lud ); return -1; } if(! lud->lud_port ) { lud->lud_port = LDAP_PORT; } #else l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme ); if(! lud->lud_port ) { lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT; } #endif port = (unsigned short) lud->lud_port; tmp = ldap_pvt_url_scheme2proto(lud->lud_scheme); if ( tmp == LDAP_PROTO_IPC ) { #ifdef LDAP_PF_LOCAL if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) { err = slap_get_listener_addresses(LDAPI_SOCK, 0, &sal); } else { err = slap_get_listener_addresses(lud->lud_host, 0, &sal); } #else #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_open_listener: URL scheme is not supported: %s\n", url, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon: URL scheme not supported: %s", url, 0, 0); #endif ldap_free_urldesc( lud ); return -1; #endif } else { if( lud->lud_host == NULL || lud->lud_host[0] == '\0' || strcmp(lud->lud_host, "*") == 0 ) { err = slap_get_listener_addresses(NULL, port, &sal); } else { err = slap_get_listener_addresses(lud->lud_host, port, &sal); } } #ifdef LDAP_CONNECTIONLESS l.sl_is_udp = ( tmp == LDAP_PROTO_UDP ); #endif #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD) if ( lud->lud_exts ) { err = get_url_perms( lud->lud_exts, &l.sl_perms, &crit ); } else { l.sl_perms = S_IRWXU; } #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */ ldap_free_urldesc( lud ); if ( err ) { return -1; } /* If we got more than one address returned, we need to make space * for it in the slap_listeners array. */ for ( num=0; sal[num]; num++ ); if ( num > 1 ) { *listeners += num-1; slap_listeners = ch_realloc( slap_listeners, (*listeners + 1) * sizeof(Listener *) ); } psal = sal; while ( *sal != NULL ) { switch( (*sal)->sa_family ) { case AF_INET: #ifdef LDAP_PF_INET6 case AF_INET6: #endif #ifdef LDAP_PF_LOCAL case AF_LOCAL: #endif break; default: sal++; continue; } #ifdef LDAP_CONNECTIONLESS if( l.sl_is_udp ) socktype = SOCK_DGRAM; #endif l.sl_sd = socket( (*sal)->sa_family, socktype, 0); if ( l.sl_sd == AC_SOCKET_INVALID ) { int err = sock_errno(); #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, "slap_open_listener: socket() failed errno=%d (%s)\n", err, sock_errstr(err), 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon: socket() failed errno=%d (%s)\n", err, sock_errstr(err), 0 ); #endif sal++; continue; } #ifndef HAVE_WINSOCK if ( l.sl_sd >= dtblsize ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, "slap_open_listener: listener descriptor %ld is too " "great %ld\n", (long)l.sl_sd, (long)dtblsize, 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon: listener descriptor %ld is too great %ld\n", (long) l.sl_sd, (long) dtblsize, 0 ); #endif tcp_close( l.sl_sd ); sal++; continue; } #endif #ifdef LDAP_PF_LOCAL if ( (*sal)->sa_family == AF_LOCAL ) { unlink ( ((struct sockaddr_un *)*sal)->sun_path ); } else #endif { #ifdef SO_REUSEADDR /* enable address reuse */ tmp = 1; rc = setsockopt( l.sl_sd, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof(tmp) ); if ( rc == AC_SOCKET_ERROR ) { int err = sock_errno(); #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_open_listener: setsockopt( %ld, SO_REUSEADDR ) " "failed errno %d (%s)\n", (long)l.sl_sd, err, sock_errstr(err) ); #else Debug( LDAP_DEBUG_ANY, "slapd(%ld): setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n", (long) l.sl_sd, err, sock_errstr(err) ); #endif } #endif } switch( (*sal)->sa_family ) { case AF_INET: addrlen = sizeof(struct sockaddr_in); break; #ifdef LDAP_PF_INET6 case AF_INET6: #ifdef IPV6_V6ONLY /* Try to use IPv6 sockets for IPv6 only */ tmp = 1; rc = setsockopt( l.sl_sd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &tmp, sizeof(tmp) ); if ( rc == AC_SOCKET_ERROR ) { int err = sock_errno(); #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_open_listener: setsockopt( %ld, IPV6_V6ONLY ) failed errno %d (%s)\n", (long)l.sl_sd, err, sock_errstr(err) ); #else Debug( LDAP_DEBUG_ANY, "slapd(%ld): setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n", (long) l.sl_sd, err, sock_errstr(err) ); #endif } #endif addrlen = sizeof(struct sockaddr_in6); break; #endif #ifdef LDAP_PF_LOCAL case AF_LOCAL: addrlen = sizeof(struct sockaddr_un); break; #endif } if (bind(l.sl_sd, *sal, addrlen)) { err = sock_errno(); #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_open_listener: bind(%ld) failed errno=%d (%s)\n", (long)l.sl_sd, err, sock_errstr(err) ); #else Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed errno=%d (%s)\n", (long) l.sl_sd, err, sock_errstr(err) ); #endif tcp_close( l.sl_sd ); sal++; continue; } switch ( (*sal)->sa_family ) { #ifdef LDAP_PF_LOCAL case AF_LOCAL: { char *addr = ((struct sockaddr_un *)*sal)->sun_path; if ( chmod( addr, l.sl_perms ) < 0 && crit ) { int err = sock_errno(); #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_open_listener: fchmod(%ld) failed errno=%d (%s)\n", (long)l.sl_sd, err, sock_errstr(err) ); #else Debug( LDAP_DEBUG_ANY, "daemon: fchmod(%ld) failed errno=%d (%s)", (long) l.sl_sd, err, sock_errstr(err) ); #endif tcp_close( l.sl_sd ); slap_free_listener_addresses(psal); return -1; } l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1; l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 ); snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, "PATH=%s", addr ); } break; #endif /* LDAP_PF_LOCAL */ case AF_INET: { char *s; #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) char addr[INET_ADDRSTRLEN]; inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr, addr, sizeof(addr) ); s = addr; #else s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr ); #endif port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port ); l.sl_name.bv_val = ber_memalloc( sizeof("IP=255.255.255.255:65535") ); snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"), "IP=%s:%d", s != NULL ? s : SLAP_STRING_UNKNOWN, port ); l.sl_name.bv_len = strlen( l.sl_name.bv_val ); } break; #ifdef LDAP_PF_INET6 case AF_INET6: { char addr[INET6_ADDRSTRLEN]; inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr, addr, sizeof addr); port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port ); l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535"); l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len ); snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d", addr, port ); l.sl_name.bv_len = strlen( l.sl_name.bv_val ); } break; #endif /* LDAP_PF_INET6 */ default: #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_open_listener: unsupported address family (%d)\n", (int)(*sal)->sa_family, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n", (int) (*sal)->sa_family, 0, 0 ); #endif break; } AC_MEMCPY(&l.sl_sa, *sal, addrlen); ber_str2bv( url, 0, 1, &l.sl_url); li = ch_malloc( sizeof( Listener ) ); *li = l; slap_listeners[*cur] = li; (*cur)++; sal++; } /* while ( *sal != NULL ) */ slap_free_listener_addresses(psal); if ( l.sl_url.bv_val == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, RESULTS, "slap_open_listener: failed on %s\n", url, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "slap_open_listener: failed on %s\n", url, 0, 0 ); #endif return -1; } #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, RESULTS, "slap_open_listener: daemon initialized %s\n", l.sl_url.bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n", l.sl_url.bv_val, 0, 0 ); #endif return 0; }
static void addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen ) { LDAPMod **pmods; int i, j; struct berval *bvp; pmods = *pmodsp; modop |= LDAP_MOD_BVALUES; i = 0; if ( pmods != NULL ) { for ( ; pmods[ i ] != NULL; ++i ) { if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 && pmods[ i ]->mod_op == modop ) { break; } } } if ( pmods == NULL || pmods[ i ] == NULL ) { if (( pmods = (LDAPMod **)realloc( pmods, (i + 2) * sizeof( LDAPMod * ))) == NULL ) { tester_perror( "realloc", NULL ); exit( EXIT_FAILURE ); } *pmodsp = pmods; pmods[ i + 1 ] = NULL; if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod ))) == NULL ) { tester_perror( "calloc", NULL ); exit( EXIT_FAILURE ); } pmods[ i ]->mod_op = modop; if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) { tester_perror( "strdup", NULL ); exit( EXIT_FAILURE ); } } if ( value != NULL ) { j = 0; if ( pmods[ i ]->mod_bvalues != NULL ) { for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) { ; } } if (( pmods[ i ]->mod_bvalues = (struct berval **)ber_memrealloc( pmods[ i ]->mod_bvalues, (j + 2) * sizeof( struct berval * ))) == NULL ) { tester_perror( "ber_memrealloc", NULL ); exit( EXIT_FAILURE ); } pmods[ i ]->mod_bvalues[ j + 1 ] = NULL; if (( bvp = (struct berval *)ber_memalloc( sizeof( struct berval ))) == NULL ) { tester_perror( "ber_memalloc", NULL ); exit( EXIT_FAILURE ); } pmods[ i ]->mod_bvalues[ j ] = bvp; bvp->bv_len = vlen; if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) { tester_perror( "malloc", NULL ); exit( EXIT_FAILURE ); } AC_MEMCPY( bvp->bv_val, value, vlen ); bvp->bv_val[ vlen ] = '\0'; } }