Esempio n. 1
0
int 
task_abandon (struct task_act *tk)
{
	struct oper_act	* on;

	DLOG(log_dsap, LLOG_TRACE, ("task_abandon"));

	for(on = tk->tk_operlist; on != NULLOPER; on = on->on_next_task) {
		on->on_state = ON_ABANDONED;
		on->on_task = NULLTASK;
		if (on->on_dsas) {
			di_desist (on->on_dsas);
			on -> on_dsas = NULL_DI_BLOCK;
		}
	}

	ds_error_free (&tk->tk_resp.di_error.de_err);
	tk->tk_resp.di_error.de_err.dse_type = DSE_ABANDONED;
	task_error(tk);

	return(OK);
}
Esempio n. 2
0
File: list.c Progetto: dank101/net-2
dsEnqError list_start()
{
  struct ds_search_arg search_arg;
  struct ds_search_result result;
  struct DSError          error;
  dsEnqError return_error;

  return_error = Okay;

  if (get_default_service (&search_arg.sra_common) != 0) {
    return localdsaerror;
  }

  search_arg.sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;

  search_arg.sra_baseobject = (*base_path != 'T'?
                               str2dn (base_path):
                               NULLDN);

  search_arg.sra_eis.eis_allattributes = FALSE;
  search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTETYPESONLY;
  search_arg.sra_eis.eis_select = 0;

  search_arg.sra_searchaliases = TRUE;
  search_arg.sra_subset = SRA_ONELEVEL;

  search_arg.sra_filter = filter_alloc();
  search_arg.sra_filter->flt_type = FILTER_NOT;
  search_arg.sra_filter->flt_next = NULLFILTER;
  search_arg.sra_filter->flt_un.flt_un_filter = filter_alloc();
  search_arg.sra_filter->flt_un.flt_un_filter->flt_type = FILTER_ITEM;
  search_arg.sra_filter->flt_un.flt_un_filter->flt_next = NULLFILTER;
  search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_type
    = FILTERITEM_EQUALITY;
  search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un.
    fi_un_ava.ava_type = AttrT_new("2.5.4.0");

  search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un.
    fi_un_ava.ava_value =
      str2AttrV("dsa", search_arg.sra_filter->flt_un.flt_un_filter->
                flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->
                oa_syntax);

#ifndef NO_STATS
  LLOG (log_stat,LLOG_NOTICE,("search +%s,extent %d, val objectClass != dsa",
			      base_path,search_arg.sra_subset));
#endif

  if (search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.
      fi_un.fi_un_ava.ava_value == NULLAttrV) {
    return_error = localdsaerror;
  } else if (ds_search (&search_arg, &error, &result) != DS_OK) {
    free_seq(dnseq);
    dnseq = NULLDS;
    dn_number = 0;
    log_ds_error(&error);
    ds_error_free(&error);
    switch (error.dse_type) {
    case DSE_LOCALERROR:
      return_error = duaerror;
      break;
    case DSE_REMOTEERROR:
      return_error = localdsaerror;
      break;
    case DSE_ATTRIBUTEERROR:
      return_error = attributerror;
      break;
    case DSE_REFERRAL:
    case DSE_DSAREFERRAL:
      return_error = remotedsaerror;
      break;
    case DSE_SECURITYERROR:
      return_error = security;
      break;
    case DSE_NAMEERROR:
      return_error = namerror;
      break;
    case DSE_SERVICEERROR:
      return_error = serviceerror;
      break;
    default:
      return_error = localdsaerror;
      break;
    }
  } else {
    dn_number = 0;
    if (result.CSR_entries != NULLENTRYINFO) {
      register EntryInfo *ptr;
      
      free_seq(dnseq);
      dnseq = NULLDS;
      dn_number = 0;

      for (ptr = result.CSR_entries; ptr != NULLENTRYINFO;
           ptr = ptr->ent_next) {
        dn_number++;
        dn2buf ((caddr_t)ptr->ent_dn, goto_path);
        add_seq (&dnseq, goto_path);
      }

      if (dn_number) dnseq = SortList(dnseq);
    } else if (result.CSR_limitproblem == LSR_NOLIMITPROBLEM) {
      free_seq(dnseq);
      dnseq = NULLDS;
      dn_number = 0;
      return_error = nothingfound;
    }

    if (result.CSR_limitproblem != LSR_NOLIMITPROBLEM) {
      switch (result.CSR_limitproblem) {
      case LSR_TIMELIMITEXCEEDED:
	if (dn_number > 0) return_error = timelimit_w_partial;
	else {
	  free_seq(dnseq);
	  dnseq = NULLDS;
	  return_error = timelimit;
	}
	break;
      case LSR_SIZELIMITEXCEEDED:
	return_error = listsizelimit;
	break;
      case LSR_ADMINSIZEEXCEEDED:
	if (dn_number > 0) return_error = adminlimit_w_partial;
	else {
	  free_seq(dnseq);
	  dnseq = NULLDS;
	  return_error = adminlimit;
	}
	break;
      }
    }
    if (result.CSR_entries) entryinfo_free(result.CSR_entries, 0);
  }
  entry_number = dn_number;
  filter_free(search_arg.sra_filter);
  dn_free(search_arg.sra_baseobject);
  ds_error_free(&error);
  return return_error;
}
Esempio n. 3
0
int 
really_find_entry (
    DN object,
    int deref,
    struct dn_seq *dn_stack,
    int master,	/* Generate only master references - NB
				   does not imply returned entry is master */
    Entry *ent_p,
    struct DSError *err,
    struct di_block **di_p
)
{
	Entry parent;
	Avlnode *kids;
	int entryrdn_cmp ();
	RDN b_rdn;
	DN     tdn, dn, dn_trail = NULLDN;
	DN     aliasdn = NULLDN;
	int rdns, aliases;

	DLOG (log_dsap,LLOG_TRACE,("really find entry"));

	if (deref == -2) {
		/* alias loop */
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
		err->ERR_NAME.DSE_na_matched = NULLDN;
		return (DS_X500_ERROR);
	}

	if (database_root == NULLENTRY) {
		LLOG (log_dsap,LLOG_NOTICE,("null root !!!"));
		return(dsa_info_parent(object, err, di_p, master));
	}

	if ((dn = object) == NULLDN) {
		DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: database_root"));
		(*ent_p) = database_root;
		return (DS_OK);
	}

	b_rdn = dn->dn_rdn;
	if ((kids = database_root->e_children) == NULLAVL) {
		DLOG(log_dsap, LLOG_DEBUG, ("database->e_child == NULLENTRY"));
		return (no_reply_child (object,dn,dn_stack,master,database_root,err,di_p));
	}

	parent = database_root;

	for(rdns = 1, aliases = 0 ; ; rdns++ ) { /* break or return out */
		*ent_p = (Entry) avl_find(kids, (caddr_t) b_rdn, entryrdn_cmp);
		if ( *ent_p == NULLENTRY ) {
			int res = no_reply_edb(object, dn_trail, dn_stack,
								   master, parent, err, di_p);
			if (res == DS_CONTINUE)
				di_rdns (*di_p,rdns,aliases,NULLDN);
			if (aliasdn)
				dn_free (aliasdn);
			return res;
		}

		if ( (*ent_p)->e_alias != NULLDN )
			/* got an alias entry */
			if (deref != FALSE) {
				Entry	  new_entry;
				int	  new_deref;
				DN 	  t_aliasdn;

				err->dse_type = DSE_NAMEERROR;
				new_deref = (deref == -1) ? -2 : -1;
				switch(really_find_entry ((*ent_p)->e_alias,new_deref,dn_stack,master,&(new_entry),err,di_p)) {
				case DS_OK:
					DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:OK"));
					(*ent_p) = new_entry;
					t_aliasdn = aliasdn;
					aliasdn = get_copy_dn(new_entry);
					aliases = 0;
					for (tdn=aliasdn; tdn != NULLDN; tdn=tdn->dn_parent)
						aliases++;

					tdn = dn->dn_parent;
					if (aliasdn == NULLDN)
						dn = aliasdn = dn_cpy(tdn);
					else {
						for (dn = aliasdn;
								dn->dn_parent != NULLDN;
								dn = dn->dn_parent)
							;
						dn->dn_parent = dn_cpy(tdn);
					}
					if (t_aliasdn)
						dn_free (t_aliasdn);

					object = aliasdn;
					break;
				case DS_CONTINUE:
					DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:CONT"));
#ifdef DEBUG
					di_list_log((*di_p));
#endif
					t_aliasdn = aliasdn;
					aliasdn = dn_cpy ((*ent_p)->e_alias);
					aliases = 0;
					for (tdn=aliasdn; tdn != NULLDN; tdn=tdn->dn_parent)
						aliases++;

					tdn = dn->dn_parent;
					if (aliasdn == NULLDN)
						dn = aliasdn = dn_cpy(tdn);
					else {
						for (dn = aliasdn;
								dn->dn_parent != NULLDN;
								dn = dn->dn_parent)
							;
						dn->dn_parent = dn_cpy(tdn);
					}
					if (t_aliasdn)
						dn_free (t_aliasdn);

					di_rdns (*di_p,rdns,aliases,aliasdn);

					if (aliasdn)
						dn_free (aliasdn);
					return(DS_CONTINUE);
				case DS_X500_ERROR:
					DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:X500ERR"));
					if ((err->dse_type == DSE_NAMEERROR) &&
							( err->ERR_NAME.DSE_na_problem == DSE_NA_ALIASDEREFERENCE)) {
						if (err->ERR_NAME.DSE_na_matched == NULLDN) {
							DN tmp_dn;
							tmp_dn = dn->dn_parent;
							dn->dn_parent = NULLDN;
							err->ERR_NAME.DSE_na_matched = dn_cpy(object);
							dn->dn_parent = tmp_dn;
							pslog (log_dsap,LLOG_EXCEPTIONS,"Alias deref Problem",(IFP)dn_print,(caddr_t)err->ERR_NAME.DSE_na_matched);
						}
						if (aliasdn)
							dn_free (aliasdn);
						return (DS_X500_ERROR);
					} else {
						ds_error_free (err);
						err->dse_type = DSE_NAMEERROR;
						err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASPROBLEM;
						err->ERR_NAME.DSE_na_matched = dn_cpy((*ent_p)->e_alias);
						pslog (log_dsap,LLOG_EXCEPTIONS,"Alias Problem",(IFP)dn_print,(caddr_t)err->ERR_NAME.DSE_na_matched);
						if (aliasdn)
							dn_free (aliasdn);
						return (DS_X500_ERROR);
					}
				default:
					if (aliasdn)
						dn_free (aliasdn);
					DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:localerror"));
					return(DS_ERROR_LOCAL);
				}


			} else if ( dn->dn_parent == NULLDN) {
				DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: ?1"));
				if (aliasdn)
					dn_free (aliasdn);
				return(DS_OK);
			} else {
				/* alias on route - error in this case */
				DN tmp_dn;
				err->dse_type = DSE_NAMEERROR;
				err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
				tmp_dn = dn->dn_parent;
				dn->dn_parent = NULLDN;
				err->ERR_NAME.DSE_na_matched = dn_cpy(object);
				dn->dn_parent = tmp_dn;
				pslog (log_dsap,LLOG_EXCEPTIONS,"Alias deref(2) Problem",(IFP)dn_print,(caddr_t)err->ERR_NAME.DSE_na_matched);
				if (aliasdn)
					dn_free (aliasdn);
				return (DS_X500_ERROR);
			}


		if (dn->dn_parent == NULLDN) {
			DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: ?2"));
			if (aliasdn)
				dn_free (aliasdn);
			return (DS_OK);
		}

		if ((*ent_p)->e_children == NULLAVL) {
			int res = no_reply_child (object,dn,dn_stack,master,(*ent_p),err,di_p);
			if (res == DS_CONTINUE)
				di_rdns (*di_p,rdns,aliases,NULLDN);

			if (aliasdn)
				dn_free (aliasdn);
			return res;
		}

		dn_trail = dn;
		dn = dn->dn_parent;
		b_rdn = dn->dn_rdn;

		kids = (*ent_p)->e_children;
		parent = *ent_p;
	}
	/* NOTREACHED */
}
Esempio n. 4
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);
	}
}
Esempio n. 5
0
int 
timeout_task (struct task_act *tk)
{
	struct oper_act	* on;
	struct DSError	* err = &(tk->tk_resp.di_error.de_err);
	struct ds_search_task *tmp;

	DLOG(log_dsap, LLOG_TRACE, ("timeout_task"));
	for(on=tk->tk_operlist; on!=NULLOPER; on=on->on_next_task) {
		/* Time out operations started by task */
		on->on_state = ON_ABANDONED;
		on->on_task = NULLTASK;
		if (on->on_dsas) {
			di_desist (on->on_dsas);
			on -> on_dsas = NULL_DI_BLOCK;
		}

	}

	if(tk->tk_dx.dx_arg.dca_dsarg.arg_type != OP_SEARCH) {
		ds_error_free (err);
		err->dse_type = DSE_SERVICEERROR;
		if (tk->tk_timed == TRUE)
			err->ERR_SERVICE.DSE_sv_problem = DSE_SV_TIMELIMITEXCEEDED;
		else /* tk->tk_timed == 2 */
			err->ERR_SERVICE.DSE_sv_problem = DSE_SV_ADMINLIMITEXCEEDED;
		task_error(tk);
		task_extract(tk);
	} else {
		/* Do search collation */
		if ((tk->tk_state == TK_ACTIVE) && (tk->local_st == NULL_ST)) {
			ds_error_free (err);
			/* nothing happened yet... */
			err->dse_type = DSE_SERVICEERROR;
			if (tk->tk_timed == TRUE)
				err->ERR_SERVICE.DSE_sv_problem = DSE_SV_TIMELIMITEXCEEDED;
			else /* tk->tk_timed == 2 */
				err->ERR_SERVICE.DSE_sv_problem = DSE_SV_ADMINLIMITEXCEEDED;
			task_error(tk);
		} else {
			/* send the results we have got... */
			tk->tk_result = &(tk->tk_resp.di_result.dr_res);
			tk->tk_result->dcr_dsres.result_type = tk->tk_dx.dx_arg.dca_dsarg.arg_type;
			tk->tk_resp.di_type = DI_RESULT;
			if (tk->tk_timed == TRUE)
				tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.CSR_limitproblem = LSR_TIMELIMITEXCEEDED;
			else /* tk->tk_timed == 2 */
				tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.CSR_limitproblem = LSR_ADMINSIZEEXCEEDED;

			/* Go through sub-tasks and add a POQ for each */
			for(tmp=tk->referred_st; tmp!= NULL_ST; tmp=tmp->st_next)
				add_cref2poq (&tk->tk_result->dcr_dsres.res_sr,tmp->st_cr);

			task_result(tk);

			st_free_dis(&tk->referred_st,1);
		}

		task_extract(tk);
	}

}
Esempio n. 6
0
int 
oper_result (struct connection *cn, struct DSAPindication *di)
{
	struct DSAPresult	* dr = &(di->di_result);
	struct oper_act *   on;

	DLOG(log_dsap, LLOG_TRACE, ("oper_result()"));

	for(on=cn->cn_operlist; on != NULLOPER; on=on->on_next_conn) {
		if(on->on_id == dr->dr_id)
			break;
	}

	if(on == NULLOPER) {
		LLOG(log_dsap, LLOG_FATAL, ("Cannot find operation to match result"));
		ds_res_free (&dr->dr_res.dcr_dsres);
		send_ro_ureject(cn->cn_ad, &(dr->dr_id), ROS_RRP_UNRECOG);
		return;
	}

#ifndef NO_STATS
	LLOG(log_stat, LLOG_DEBUG, ("Result received (%d) [%d]",
								on->on_conn->cn_ad,
								on->on_id));
#endif

	if(on->on_state == ON_ABANDONED) {
		LLOG(log_dsap, LLOG_TRACE, ("oper_result - operation had been abandoned"));

		/* If we have the arguments we could do more caching here. */
		if (dr->dr_res.dcr_dsres.result_type == OP_READ)
			 cache_dsp_entry (&dr->dr_res.dcr_dsres.res_rd.rdr_entry);

		ds_res_free (&dr->dr_res.dcr_dsres);
		oper_extract(on);
		return;
	}

	if (dr->dr_res.dcr_dsres.result_type != on->on_arg->dca_dsarg.arg_type) {
		LLOG(log_dsap, LLOG_TRACE, ("oper_result - operation had been abandoned (2)"));
		send_ro_ureject(on->on_conn->cn_ad, &(dr->dr_id), ROS_RRP_MISTYPED);
		ds_res_free (&dr->dr_res.dcr_dsres);
		oper_extract(on);
		return;
	}

	/* free previous error - if any */
	ds_error_free (&on->on_resp.di_error.de_err);

	on->on_resp = (*di);	/* struct copy */

	cn->cn_last_used = timenow;

	switch(on->on_type) {
	case ON_TYPE_X500:
		task_result_wakeup (on);
		break;
	case ON_TYPE_SUBTASK:
		subtask_result_wakeup (on);
		break;
	case ON_TYPE_BIND_COMPARE:
		bind_compare_result_wakeup(on);
		ds_res_free (&dr->dr_res.dcr_dsres);
		break;
	case ON_TYPE_GET_DSA_INFO:
		dsa_info_result_wakeup(on);
		ds_res_free (&dr->dr_res.dcr_dsres);
		break;
	case ON_TYPE_GET_EDB:
	case ON_TYPE_SHADOW:
		on->on_state = ON_COMPLETE;
		break;
	default:
		LLOG(log_dsap, LLOG_EXCEPTIONS, ("oper_result: operation of unknown type"));
		oper_extract(on);
		break;
	}
}
Esempio n. 7
0
dsEnqError srch_start()
{
  struct ds_search_arg search_arg;
  struct ds_search_result result;
  struct DSError          error;
  dsEnqError return_error;
  extern Filter make_filter();
  DN curr_rdn;

  if (*mvalue == '\0') {
    return list_start();
  }

  if (get_default_service (&search_arg.sra_common) != 0) {
    return nothingfound;
  }

  search_arg.sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;

  curr_rdn = search_arg.sra_baseobject = (*base_path != 'T'?
					  str2dn (base_path):
					  NULLDN);

  search_arg.sra_eis.eis_allattributes = FALSE;
  search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTETYPESONLY;
  search_arg.sra_eis.eis_select = 0;
  search_arg.sra_searchaliases = TRUE;

  search_arg.sra_subset = SRA_ONELEVEL;
  while (curr_rdn != NULLDN) {
    if (!strcmp(curr_rdn->dn_rdn->rdn_at->oa_ot.ot_stroid, 
		"2.5.4.10")) {
      search_arg.sra_subset = SRA_WHOLESUBTREE;
      break;
    }
    curr_rdn = curr_rdn->dn_parent;
  }

  if ((search_arg.sra_filter = make_filter(filt_arr[typeindx])) == NULLFILTER)
    return duaerror;

#ifndef NO_STATS
  LLOG (log_stat, LLOG_NOTICE, ("search +%s, extent %d, val %s",
                                base_path,search_arg.sra_subset, mvalue));
#endif

  if(ds_search (&search_arg, &error, &result) != DS_OK) {
    /* deal with error */
    free_seq(dnseq);
    dnseq = NULLDS;
    dn_number = 0;
    log_ds_error(&error);
    ds_error_free(&error);
    switch (error.dse_type) {
    case DSE_LOCALERROR:
      return_error = duaerror;
      break;
    case DSE_REMOTEERROR:
      return_error = localdsaerror;
      break;
    case DSE_ATTRIBUTEERROR:
      return_error = attributerror;
      break;
    case DSE_REFERRAL:
    case DSE_DSAREFERRAL:
      return_error = remotedsaerror;
      break;
    case DSE_SECURITYERROR:
      return_error = security;
      break;
    case DSE_NAMEERROR:
      return_error = namerror;
      break;
    case DSE_SERVICEERROR:
      return_error = serviceerror;
      break;
    default:
      return_error = localdsaerror;
      break;
    }
  } else {
    correlate_search_results (&result);
    dn_number = 0;

    if (result.CSR_entries != NULLENTRYINFO) {
      register EntryInfo *ptr;

      return_error = Okay;
      free_seq(dnseq);
      dnseq = NULLDS;
      dn_number = 0;

      for (ptr = result.CSR_entries;
           ptr != NULLENTRYINFO; 
	   ptr = ptr->ent_next){
        dn_number++;
        dn2buf((caddr_t) ptr->ent_dn, goto_path);
        add_seq(&dnseq, goto_path);
      }

      if (dn_number) dnseq = SortList(dnseq);
    } else if (result.CSR_limitproblem == LSR_NOLIMITPROBLEM) {
      free_seq(dnseq);
      dnseq = NULLDS;
      dn_number = 0;
      return_error = nothingfound;
    }

    if(result.CSR_limitproblem != LSR_NOLIMITPROBLEM) {
      switch (result.CSR_limitproblem) {
      case LSR_TIMELIMITEXCEEDED:
	if (dn_number > 0) return_error = timelimit_w_partial;
	else {
	  free_seq(dnseq);
	  dnseq = NULLDS;
	  return_error = timelimit;
	}
	break;
      case LSR_SIZELIMITEXCEEDED:
	return_error = listsizelimit;
	break;
      case LSR_ADMINSIZEEXCEEDED:
	if (dn_number > 0) return_error = adminlimit_w_partial;
	else {
	  free_seq(dnseq);
	  dnseq = NULLDS;
	  return_error = adminlimit;
	}
	break;
      }
      entryinfo_free(result.CSR_entries, 0);
    }
  }
  entry_number = dn_number;
  filter_free(search_arg.sra_filter);
  dn_free(search_arg.sra_baseobject);
  ds_error_free(&error);
  return return_error;
}
Esempio n. 8
0
int 
task_chain (struct task_act *tk, struct di_block *di)
{
	struct oper_act	* on;
	struct DSError	* err = &(tk->tk_resp.di_error.de_err);
	struct di_block	* di_tmp;
	char		refer_ok = TRUE;

#ifdef DEBUG
	DLOG(log_dsap, LLOG_DEBUG, ("task_chain called with:"));
	di_list_log(di);
#endif

	/* NB At some point this routine must assign the di_block list to
	* either the task (if it is intended to geneate a referral) or to
	* an operation hanging off that task if it is intended to chain the
	* task. This is fine when there are no deferred di_blocks, but when
	* there are then the information they will eventually contain is
	* needed to make a full decision on whether to chain or refer.
	* This needs a lot of thought to get right, for now the chain/refer
	* decision is made once and for all on the basis of the information
	* available now. Any information not available is assumed to force a
	* referral (the safe option  -  until network connectivity is considered)!
	* THis may introduce the unwelcome effect that a first request to a
	* DSA may produce a referral where subsequent requests do not - so much
	* for consistency but it won't happen that often if DSA info is cached
	* sensibly.
	*/

	/*
	*  Generate the referral which the DSA will pass back if
	*  chaining is disallowed or oper_chain fails for all
	*  DSAs listed.
	*/

	sort_dsa_list (&di);

	if ((di_tmp = select_refer_dsa (di,tk)) == NULL_DI_BLOCK) {
		/* The remote END is probably unable to follow the referral - chain if allowed */
		refer_ok = FALSE;
		for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) {
			if(di_tmp->di_state == DI_DEFERRED)
				continue;

#ifdef DEBUG
			DLOG(log_dsap, LLOG_DEBUG, ("About to call di2cref with:"));
			di_log(di_tmp);
#endif
			if(di2cref(di_tmp, err, tk->tk_conn->cn_ctx) == OK)
				break;
		}
	} else if (di2cref(di_tmp, err, tk->tk_conn->cn_ctx) != OK)
		di_tmp = NULL_DI_BLOCK;	/* waiting... */

	if(di_tmp == NULL_DI_BLOCK) {
		/*
		*  Want to generate a referral - but all di_blocks (if any)
		*  are deferred. Would we be lying too much if we said the
		*  DSA was "busy" at this point???
		*/
		ds_error_free (err);
		err->dse_type = DSE_SERVICEERROR;
		err->ERR_SERVICE.DSE_sv_problem = DSE_SV_BUSY;
		di_desist(di);
		return(NOTOK);
	}

	/*
	*  If it would be inappropriate to chain this operation, then
	*  generate a referral from the di_block list.
	*/

	if(chain_ok(tk,refer_ok,di_tmp->di_dn) == FALSE) {
		DLOG(log_dsap, LLOG_DEBUG, ("Referring!"));
		di_desist(di);
		return(NOTOK);
	}

	DLOG(log_dsap, LLOG_DEBUG, ("Chaining!"));
	/* Chain. Generate the new operation to send */
	if((on = task2oper(tk)) == NULLOPER) {
		DLOG(log_dsap, LLOG_DEBUG, ("Why did task2oper fail??"));
		ds_error_free (err);
		err->dse_type = DSE_SERVICEERROR;
		err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE;
		di_desist(di);
		return(NOTOK);
	}

	if(ti_is_elem(tk->tk_dx.dx_arg.dca_charg.cha_trace,
				  tk->tk_dx.dx_arg.dca_charg.cha_trace->ti_next)) {
		DLOG (log_dsap,LLOG_TRACE,("Loop found in oper_chain()"));
		ds_error_free (err);
		err->dse_type = DSE_SERVICEERROR;
		err->ERR_SERVICE.DSE_sv_problem = DSE_SV_LOOPDETECT;
		return(NOTOK);
	}

	on->on_next_task = tk->tk_operlist;
	tk->tk_operlist = on;
	on->on_task = tk;

	/* Hand control of di_blocks to the operation */
	on->on_dsas = di;
	for(di_tmp = di; 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) {
		oper_task_extract(on);
		oper_free(on);
		return(NOTOK);
	}

#ifdef QUIPU_CONSOLE
	/* SPT trying to insert a chain_analyse here. */
	/* The aim is to add this chained command to */
	/* the open_call_avs structure */

	chaining_analyse(tk, di) ;
#endif /* QUIPU_CONSOLE */

	return(OK);
}