void out_free(void *block, oskit_size_t size) { check_guard("post", block+size); block -= GUARD_SIZE; size += GUARD_SIZE * 2; check_guard("pre", block); scrub(block,size); in_free(block,size); }
int main(int argc, char **argv) { assert_cmpnum(argc, 2); int openfd = dup(1); int dirfd = -1; assert_cmpnum_op(openfd, >, 0); std::string exepath(argv[1]); std::string::size_type slpos = exepath.rfind('/'); exepath.erase(slpos); check_guard(openfd, dirfd, exepath); check_notdir(argv[1], exepath); assert_cmpnum_op(dirfd, >, 0); struct stat st; // the descriptors should be closed now, so fstat() should fail assert_cmpnum(fstat(openfd, &st), -1); assert_cmpnum(fstat(dirfd, &st), -1); return 0; }
int ds_bind_init (struct connection *cn) { struct ds_bind_arg * arg = &(cn->cn_start.cs_ds.ds_bind_arg); struct ds_bind_arg * result = &(cn->cn_start.cs_res); struct ds_bind_error * error = &(cn->cn_start.cs_err); Attr_Sequence as; Entry entryptr; extern AttributeType at_password; extern AttributeType at_p_password; struct di_block * dsas = NULL_DI_BLOCK; struct di_block * di_tmp; struct oper_act * on; struct ds_compare_arg * cma; struct DSError err; static struct common_args ca_def = default_common_args; int res; int retval; struct protected_password * pp; #ifndef NO_STATS char buff[LINESIZE]; #endif extern struct SecurityServices *dsap_security; DLOG (log_dsap,LLOG_TRACE,("ds_bind_init")); if ( (arg->dba_version != DBA_VERSION_V1988) || quipu_shutdown) { error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SERVICE; error->dbe_value = DSE_SV_UNAVAILABLE; return(DS_ERROR_CONNECT); } /* We don't support any bilaterally-defined authentication procedures. * Hence, if we get EXTERNAL credentials in the bind, reject them. */ if (arg->dba_auth_type == DBA_AUTH_EXTERNAL) { DLOG(log_dsap, LLOG_EXCEPTIONS, ("EXTERNAL found in credentials")); error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SERVICE; error->dbe_value = DSE_SV_UNAVAILABLE; return (DS_ERROR_CONNECT); } /* If password is present, but zero length, treat as though absent */ if ((arg->dba_auth_type == DBA_AUTH_SIMPLE) && (arg->dba_passwd_len == 0)) arg->dba_auth_type = DBA_AUTH_NONE; switch (arg->dba_auth_type) { case DBA_AUTH_NONE: if (((arg->dba_dn == NULLDN) && auth_bind == 1) || (auth_bind > 1)) { out: ; #ifndef NO_STATS if (arg->dba_dn == NULLDN) LLOG(log_stat, LLOG_TRACE, ("Bind (%d) (rejected)", cn->cn_ad)); else { sprintf (buff,"Bind (%d) (rejected)",cn->cn_ad); pslog (log_stat,LLOG_TRACE,buff,(IFP)dn_print, (caddr_t)arg->dba_dn); } #endif error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_AUTHENTICATION; return (DS_ERROR_CONNECT); } break; case DBA_AUTH_SIMPLE: if (auth_bind > 2) goto out; break; case DBA_AUTH_PROTECTED: if (auth_bind > 3) goto out; break; case DBA_AUTH_STRONG: break; case DBA_AUTH_EXTERNAL: goto out; } if (arg->dba_dn == NULLDN) { #ifndef NO_STATS LLOG(log_stat, LLOG_NOTICE, ("Bind (%d) (anonymous)", cn->cn_ad)); #endif cn->cn_authen = DBA_AUTH_NONE; make_dsa_bind_arg(result); return(DS_OK); } /* Now we're sure dba_dn contains a valid pointer, can decode it */ if ( ! check_prefix_list (arg->dba_dn)) { #ifndef NO_STATS sprintf (buff,"Bind (%d) (reject - prefix)",cn->cn_ad); pslog (log_stat,LLOG_TRACE,buff,(IFP)dn_print, (caddr_t)arg->dba_dn); #endif error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_ACCESSRIGHTS; return (DS_ERROR_CONNECT); } if ((cn->cn_ctx == DS_CTX_X500_DAP) && !(check_dn_length(arg->dba_dn))) { #ifndef NO_STATS sprintf (buff,"Bind (%d) (reject - DAP length)",cn->cn_ad); pslog (log_stat,LLOG_TRACE,buff,(IFP)dn_print, (caddr_t)arg->dba_dn); #endif error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_ACCESSRIGHTS; return (DS_ERROR_CONNECT); } switch (arg->dba_auth_type) { case DBA_AUTH_NONE: /* partially check DN - i.e see if we can say if DEFINATELY does */ /* not exist. If it possibly exists - allow bind, checking it */ /* runs the risk of livelock */ switch (res = really_find_entry(arg->dba_dn, TRUE, NULLDNSEQ, FALSE, &(entryptr), &(err), &(dsas))) { case DS_X500_ERROR: if ((err.dse_type == DSE_NAMEERROR) && (err.ERR_NAME.DSE_na_problem == DSE_NA_NOSUCHOBJECT)) { ds_error_free(&(err)); #ifndef NO_STATS sprintf (buff,"Bind (%d) (no auth - rejected)",cn->cn_ad); pslog (log_stat,LLOG_TRACE,buff,(IFP)dn_print,(caddr_t)arg->dba_dn); #endif error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_INVALIDCREDENTIALS; return (DS_ERROR_CONNECT); } /* fall */ default: #ifndef NO_STATS sprintf (buff,"Bind (%d) (no auth)",cn->cn_ad); pslog (log_stat,LLOG_NOTICE,buff,(IFP)dn_print,(caddr_t)arg->dba_dn); #endif if (dsas != NULL_DI_BLOCK) di_desist (dsas); cn->cn_authen = DBA_AUTH_NONE; make_dsa_bind_arg(result); return (DS_OK); } case DBA_AUTH_SIMPLE: #ifndef NO_STATS sprintf (buff,"Bind (%d) (simple)",cn->cn_ad); pslog (log_stat,LLOG_NOTICE,buff,(IFP)dn_print,(caddr_t)arg->dba_dn); #endif /* Can't check simple credentials from DSP (livelock risk). * Hence treat DSP accesses as unauthenticated. */ if (cn->cn_ctx != DS_CTX_X500_DAP) { cn->cn_authen = DBA_AUTH_NONE; make_dsa_bind_arg(result); return(DS_OK); } break; case DBA_AUTH_PROTECTED: #ifndef NO_STATS sprintf (buff,"Bind (%d) (protected)",cn->cn_ad); pslog (log_stat,LLOG_NOTICE,buff,(IFP)dn_print,(caddr_t)arg->dba_dn); #endif if (cn->cn_ctx != DS_CTX_X500_DAP) { cn->cn_authen = DBA_AUTH_NONE; make_dsa_bind_arg(result); return(DS_OK); } else { UTC ut; long c_time, s_time, delta; time(&s_time); ut = str2utct(arg->dba_time1, strlen(arg->dba_time1)); if (ut == NULLUTC) c_time = 0L; /* 1970 is a convenient out-of-date timestamp */ else c_time = gtime(ut2tm(ut)); delta = s_time - c_time; if ((delta < 0) || (delta > bind_window)) { DLOG(log_dsap, LLOG_EXCEPTIONS, ("Time = %s, Delay = %D s : Association rejected", arg->dba_time1, delta)); error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_INVALIDCREDENTIALS; return (DS_ERROR_CONNECT); } pp = (struct protected_password *) calloc(1, sizeof(*pp)); /* Ought to check for null pointer ... */ pp->passwd = malloc((unsigned)arg->dba_passwd_len); bcopy(arg->dba_passwd, pp->passwd, arg->dba_passwd_len); pp->n_octets = arg->dba_passwd_len; pp->time1 = strdup(arg->dba_time1); pp->is_protected[0] = (char) 1; } break; case DBA_AUTH_STRONG: #ifndef NO_STATS sprintf (buff,"Bind (%d) (strong)",cn->cn_ad); pslog (log_stat,LLOG_NOTICE,buff,(IFP)dn_print,(caddr_t)arg->dba_dn); #endif /* Strong authentication is not yet supported. * It will eventually be possible to check strong credentials over DSP. * For the moment, accept them and treat as NONE over DSP, but reject * over DAP. */ if (dsap_security && dsap_security->serv_ckpath && dsap_security->serv_cknonce) { int rc; DN real_name; struct Nonce nonce; nonce.non_time1 = arg->dba_time1; nonce.non_time2 = arg->dba_time2; nonce.non_r1.n_bits = arg->dba_r1.n_bits; nonce.non_r1.value = arg->dba_r1.value; nonce.non_r2.n_bits = arg->dba_r2.n_bits; nonce.non_r2.value = arg->dba_r2.value; rc = (dsap_security->serv_cknonce)(&nonce); if (rc != OK) { error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = rc; return (DS_ERROR_CONNECT); } rc = (dsap_security->serv_ckpath)((caddr_t) arg, _ZTokenToSignDAS, &_ZDAS_mod, arg->dba_cpath, arg->dba_sig, &real_name); if (rc != OK) { error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = rc; return (DS_ERROR_CONNECT); } else { if(dn_cmp(real_name, arg->dba_dn) == OK) { make_dsa_bind_arg(result); return (DS_OK); } else { sprintf (buff,"User != Authenticated User, ie %s != ", dn2str(arg->dba_dn)); pslog (log_dsap,LLOG_NOTICE,buff,(IFP)dn_print,(caddr_t)real_name); error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_AUTHENTICATION; return (DS_ERROR_CONNECT); } } } else { if (cn->cn_ctx != DS_CTX_X500_DAP) { cn->cn_authen = DBA_AUTH_NONE; make_dsa_bind_arg(result); return (DS_OK); } else { error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SERVICE; error->dbe_value = DSE_SV_UNAVAILABLE; return (DS_ERROR_CONNECT); } } } /* If we fall through to here, credentials are simple or protected simple */ if ((res = really_find_entry(arg->dba_dn, TRUE, NULLDNSEQ, FALSE, &(entryptr), &(err), &(dsas))) == DS_OK) { /* is it really OK ??? */ if ((entryptr->e_data == E_TYPE_CONSTRUCTOR) || (entryptr->e_data == E_TYPE_CACHE_FROM_MASTER)) { DN dn_found; DLOG(log_dsap, LLOG_TRACE, ("rfe (bind) returned a constructor")); dn_found = get_copy_dn(entryptr); res = constructor_dsa_info(dn_found,NULLDNSEQ,FALSE,entryptr,&err,&dsas); dn_free (dn_found); } } switch(res) { case DS_OK: /* entryptr filled out - break through to deal with it */ break; case DS_CONTINUE: /* * At this point a remote operation is required to compare * the password given with the password of the entry, so * fire up the remote operation and return without completing. * Mark the operation as a BIND_COMPARE_OP and set the connection * which will need to be restarted. * Generate a compare argument. * Chain the compare operation using the di_blocks. */ cn->cn_start.cs_bind_compare = on = oper_alloc();/* cn knows about on */ on->on_type = ON_TYPE_BIND_COMPARE; on->on_bind_compare = cn; /* on knows about cn */ set_my_chain_args(&(on->on_req.dca_charg), arg->dba_dn); on->on_req.dca_dsarg.arg_type = OP_COMPARE; cma = &(on->on_req.dca_dsarg.arg_cm); cma->cma_common = ca_def; /* struct copy */ /* Set originator/requestor */ if (on->on_req.dca_charg.cha_originator) /* set my set_my_chain_arg */ dn_free(on->on_req.dca_charg.cha_originator); on->on_req.dca_charg.cha_originator = dn_cpy(arg->dba_dn); cma->cma_common.ca_requestor = dn_cpy(arg->dba_dn); cma->cma_common.ca_servicecontrol.svc_prio = SVC_PRIO_HIGH; cma->cma_object = dn_cpy(arg->dba_dn); if (arg->dba_auth_type == DBA_AUTH_SIMPLE) { cma->cma_purported.ava_type = AttrT_cpy (at_password); cma->cma_purported.ava_value = str2AttrV (arg->dba_passwd,str2syntax("octetstring")); } else { cma->cma_purported.ava_type = AttrT_cpy (at_p_password); cma->cma_purported.ava_value = (AttributeValue) calloc(1, sizeof(attrVal)); cma->cma_purported.ava_value->av_syntax = str2syntax("protectedPassword"); cma->cma_purported.ava_value->av_struct = (caddr_t) pp; } on->on_dsas = dsas; for(di_tmp=on->on_dsas; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) { di_tmp->di_type = DI_OPERATION; di_tmp->di_oper = on; } if(oper_chain(on) == OK) return(DS_CONTINUE); oper_extract(on); cn->cn_start.cs_bind_compare = NULLOPER; error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SERVICE; error->dbe_value = DSE_SV_UNAVAILABLE; return(DS_ERROR_CONNECT); case DS_X500_ERROR: /* User's entry doesn't exist, for example */ LLOG(log_dsap, LLOG_TRACE, ("ds_bind - really_find_entry erred:")); log_ds_error(&(err)); ds_error_free(&(err)); error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_INVALIDCREDENTIALS; return(DS_ERROR_CONNECT); default: error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SERVICE; error->dbe_value = DSE_SV_DITERROR; return(DS_ERROR_CONNECT); } if ((as = as_find_type (entryptr->e_attributes, (arg->dba_auth_type == DBA_AUTH_SIMPLE) ? at_password : at_p_password)) == NULLATTR) { /* No password in entry. * Simple authentication is not possible for entities without passwords. * Hence, give the `inappropriate authentication' message. */ error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_AUTHENTICATION; return (DS_ERROR_CONNECT); } if (arg->dba_auth_type == DBA_AUTH_SIMPLE) { if (strlen ((char *)as->attr_value->avseq_av.av_struct) != arg->dba_passwd_len) retval = -1; else retval = strncmp ((char *)as->attr_value->avseq_av.av_struct, arg->dba_passwd, arg->dba_passwd_len); } else retval = check_guard( ((struct protected_password *) as->attr_value->avseq_av.av_struct)->passwd, ((struct protected_password *) as->attr_value->avseq_av.av_struct)->n_octets, arg->dba_time1, arg->dba_passwd, arg->dba_passwd_len); if (retval == 0) { /* Password OK! */ cn->cn_authen = arg->dba_auth_type; make_dsa_bind_arg(result); return (DS_OK); } else { /* password wrong ! */ error->dbe_version = DBA_VERSION_V1988; error->dbe_type = DBE_TYPE_SECURITY; error->dbe_value = DSE_SC_INVALIDCREDENTIALS; return (DS_ERROR_CONNECT); } }