static tls_session * tlsg_session_new ( tls_ctx * ctx, int is_server ) { tlsg_ctx *c = (tlsg_ctx *)ctx; tlsg_session *session; session = ber_memcalloc ( 1, sizeof (*session) ); if ( !session ) return NULL; session->ctx = c; gnutls_init( &session->session, is_server ? GNUTLS_SERVER : GNUTLS_CLIENT ); gnutls_priority_set( session->session, c->prios ); if ( c->cred ) gnutls_credentials_set( session->session, GNUTLS_CRD_CERTIFICATE, c->cred ); if ( is_server ) { int flag = 0; if ( c->lo->ldo_tls_require_cert ) { flag = GNUTLS_CERT_REQUEST; if ( c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND || c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) flag = GNUTLS_CERT_REQUIRE; gnutls_certificate_server_set_request( session->session, flag ); } } return (tls_session *)session; }
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 int alock_read_slot ( alock_info_t * info, alock_slot_t * slot_data ) { unsigned char slotbuf [ALOCK_SLOT_SIZE]; int res, size, size_total, err; assert (info != NULL); assert (slot_data != NULL); assert (info->al_slot > 0); res = lseek (info->al_fd, (off_t) (ALOCK_SLOT_SIZE * info->al_slot), SEEK_SET); if (res == -1) return -1; size_total = 0; while (size_total < ALOCK_SLOT_SIZE) { size = read (info->al_fd, slotbuf + size_total, ALOCK_SLOT_SIZE - size_total); if (size == 0) return -1; if (size < 0) { err = errno; if (err != EINTR && err != EAGAIN) return -1; } else { size_total += size; } } if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) { return -1; } slot_data->al_lock = alock_read_iattr (slotbuf+8); slot_data->al_stamp = alock_read_iattr (slotbuf+16); slot_data->al_pid = alock_read_iattr (slotbuf+24); if (slot_data->al_appname) ber_memfree (slot_data->al_appname); slot_data->al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME); if (slot_data->al_appname == NULL) { return -1; } strncpy (slot_data->al_appname, (char *)slotbuf+32, ALOCK_MAX_APPNAME-1); (slot_data->al_appname) [ALOCK_MAX_APPNAME-1] = '\0'; return 0; }
static tls_ctx * tlsg_ctx_new ( struct ldapoptions *lo ) { tlsg_ctx *ctx; ctx = ber_memcalloc ( 1, sizeof (*ctx) ); if ( ctx ) { ctx->lo = lo; if ( gnutls_certificate_allocate_credentials( &ctx->cred )) { ber_memfree( ctx ); return NULL; } ctx->refcount = 1; gnutls_priority_init( &ctx->prios, "NORMAL", NULL ); #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_init( &ctx->ref_mutex ); #endif } return (tls_ctx *)ctx; }
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 ); }
static int read_config_file () { FILE * config; char * line; int returnValue = -1; line = ber_memcalloc(260, sizeof(char)); if ( line == NULL ) { return returnValue; } if ( (config = fopen(CONFIG_FILE, "r")) == NULL) { #if defined(DEBUG) syslog(LOG_ERR, "check_password: Opening file %s failed", CONFIG_FILE); #endif #if defined(LDEBUG) printf("check_password: Opening file %s failed\n", CONFIG_FILE); #endif ber_memfree(line); return returnValue; } returnValue = 0; while (fgets(line, 256, config) != NULL) { char *start = line; char *word, *value; validator dealer; #if defined(DEBUG) /* Debug traces to syslog. */ syslog(LOG_NOTICE, "check_password: Got line |%s|", line); #endif #if defined(LDEBUG) /* Debug traces. */ char* msg = chomp(line); printf("check_password: Got line |%s|\n", msg); ber_memfree(msg); #endif while (isspace(*start) && isascii(*start)) start++; /* If we've got punctuation, just skip the line. */ if ( ispunct(*start)) { #if defined(DEBUG) /* Debug traces to syslog. */ syslog(LOG_NOTICE, "check_password: Skipped line |%s|", line); #endif #if defined(LDEBUG) /* Debug traces. */ char* msg = chomp(line); printf("check_password: Skipped line |%s|\n", msg); ber_memfree(msg); #endif continue; } if( isascii(*start)) { struct config_entry* centry = config_entries; int i = 0; char* keyWord = centry[i].key; if ((word = strtok(start, " \t")) && (value = strtok(NULL, " \t"))) { while ( keyWord != NULL ) { if ((strncmp(keyWord,word,strlen(keyWord)) == 0) && (dealer = valid_word(word)) ) { #if defined(DEBUG) syslog(LOG_NOTICE, "check_password: Word = %s, value = %s", word, value); #endif #if defined(LDEBUG) printf("check_password: Word = %s, value = %s\n", word, value); #endif centry[i].value = chomp(value); break; } i++; keyWord = centry[i].key; } } } } fclose(config); ber_memfree(line); return returnValue; }
int alock_open ( alock_info_t * info, const char * appname, const char * envdir, int locktype ) { struct stat statbuf; alock_info_t scan_info; alock_slot_t slot_data; char * filename; int res, max_slot; int dirty_count, live_count, nosave; char *ptr; assert (info != NULL); assert (appname != NULL); assert (envdir != NULL); assert ((locktype & ALOCK_SMASK) >= 1 && (locktype & ALOCK_SMASK) <= 2); slot_data.al_lock = locktype; slot_data.al_stamp = time(NULL); slot_data.al_pid = getpid(); slot_data.al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME); if (slot_data.al_appname == NULL) { return ALOCK_UNSTABLE; } strncpy (slot_data.al_appname, appname, ALOCK_MAX_APPNAME-1); slot_data.al_appname [ALOCK_MAX_APPNAME-1] = '\0'; filename = ber_memcalloc (1, strlen (envdir) + strlen ("/alock") + 1); if (filename == NULL ) { ber_memfree (slot_data.al_appname); return ALOCK_UNSTABLE; } ptr = lutil_strcopy(filename, envdir); lutil_strcopy(ptr, "/alock"); #ifdef _WIN32 { HANDLE handle = CreateFile (filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); info->al_fd = _open_osfhandle (handle, 0); } #else info->al_fd = open (filename, O_CREAT|O_RDWR, 0666); #endif ber_memfree (filename); if (info->al_fd < 0) { ber_memfree (slot_data.al_appname); return ALOCK_UNSTABLE; } info->al_slot = 0; res = alock_grab_lock (info->al_fd, 0); if (res == -1) { close (info->al_fd); ber_memfree (slot_data.al_appname); return ALOCK_UNSTABLE; } res = fstat (info->al_fd, &statbuf); if (res == -1) { close (info->al_fd); ber_memfree (slot_data.al_appname); return ALOCK_UNSTABLE; } max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE; dirty_count = 0; live_count = 0; nosave = 0; scan_info.al_fd = info->al_fd; for (scan_info.al_slot = 1; scan_info.al_slot < max_slot; ++ scan_info.al_slot) { if (scan_info.al_slot != info->al_slot) { res = alock_query_slot (&scan_info); if (res & ALOCK_NOSAVE) { nosave = ALOCK_NOSAVE; res ^= ALOCK_NOSAVE; } if (res == ALOCK_UNLOCKED && info->al_slot == 0) { info->al_slot = scan_info.al_slot; } else if (res == ALOCK_LOCKED) { ++live_count; } else if (res == ALOCK_UNIQUE && (( locktype & ALOCK_SMASK ) == ALOCK_UNIQUE || nosave )) { close (info->al_fd); ber_memfree (slot_data.al_appname); return ALOCK_BUSY; } else if (res == ALOCK_DIRTY) { ++dirty_count; } else if (res == -1) { close (info->al_fd); ber_memfree (slot_data.al_appname); return ALOCK_UNSTABLE; } } } if (dirty_count && live_count) { close (info->al_fd); ber_memfree (slot_data.al_appname); return ALOCK_UNSTABLE; } if (info->al_slot == 0) info->al_slot = max_slot + 1; res = alock_grab_lock (info->al_fd, info->al_slot); if (res == -1) { close (info->al_fd); ber_memfree (slot_data.al_appname); return ALOCK_UNSTABLE; } res = alock_write_slot (info, &slot_data); ber_memfree (slot_data.al_appname); if (res == -1) { close (info->al_fd); return ALOCK_UNSTABLE; } alock_share_lock (info->al_fd, info->al_slot); res = alock_release_lock (info->al_fd, 0); if (res == -1) { close (info->al_fd); return ALOCK_UNSTABLE; } if (dirty_count) return ALOCK_RECOVER | nosave; return ALOCK_CLEAN | nosave; }