Exemplo n.º 1
0
int 
no_reply_edb (
    DN object,
    DN dn, 	/* tail - not matched */
    struct dn_seq *dn_stack,
    int master,
    Entry entryptr,
    struct DSError *err,
    struct di_block **di_p
)
{
	DN dn_tmp;
	Entry akid;

	DLOG (log_dsap,LLOG_TRACE,("no reply edb"));

	if (isleaf(entryptr)) {
		DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
		if (dn != NULLDN) {
			dn_tmp = dn->dn_parent;
			dn->dn_parent = NULLDN;
		} else
			object = NULLDN;
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		err->ERR_NAME.DSE_na_matched = dn_cpy (object);
		if (dn != NULLDN)
			dn->dn_parent = dn_tmp;

		return(DS_X500_ERROR);
	}

	if (entryptr->e_children == NULLAVL) {
		return(constructor_dsa_info(object,dn_stack,master,entryptr,err,di_p));
	}

	akid = (Entry) avl_getone(entryptr->e_children);
	if ((akid->e_data == E_DATA_MASTER)
			|| ((! master) && (akid->e_data == E_TYPE_SLAVE)) ) {
		DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
		if (dn != NULLDN) {
			dn_tmp = dn->dn_parent;
			dn->dn_parent = NULLDN;
		} else
			object = NULLDN;
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		err->ERR_NAME.DSE_na_matched = dn_cpy (object);
		if (dn != NULLDN)
			dn->dn_parent = dn_tmp;
		return(DS_X500_ERROR);
	}

	/* build a referral */
	return(constructor_dsa_info_aux(object,dn_stack,master,entryptr,err,di_p));
}
Exemplo n.º 2
0
int 
dsa_read_control (struct ds_read_arg *arg, struct ds_read_result *result)
{

	if ((arg->rda_eis.eis_allattributes) ||
			(arg->rda_eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY))
		return FALSE;

	if ((arg->rda_eis.eis_select == NULLATTR)
			|| (arg->rda_eis.eis_select->attr_link != NULLATTR))
		return FALSE;

	if (AttrT_cmp (at_control,arg->rda_eis.eis_select->attr_type) != 0)
		return FALSE;

	if ((result->rdr_entry.ent_attr = dsa_control_info()) == NULLATTR)
		return FALSE;

	/* Fiddle DN - for DUA caching !!! */
	result->rdr_entry.ent_dn = dn_cpy (mydsadn);

	result->rdr_entry.ent_iscopy = FALSE;
	result->rdr_entry.ent_age = (time_t) 0;
	result->rdr_entry.ent_next = NULLENTRYINFO;
	result->rdr_common.cr_requestor = NULLDN;
	result->rdr_common.cr_aliasdereferenced = FALSE;

	return TRUE;
}
Exemplo n.º 3
0
int 
no_reply_child (
    DN object,
    DN dn, 	/* tail - not matched */
    struct dn_seq *dn_stack,
    int master,
    Entry entryptr,
    struct DSError *err,
    struct di_block **di_p
)
{
	DN dn_tmp;

	DLOG (log_dsap,LLOG_TRACE,("no reply child"));

	if (isleaf(entryptr)) {
		DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
		if (dn != NULLDN) {
			dn_tmp = dn->dn_parent;
			dn->dn_parent = NULLDN;
		} else
			object = NULLDN;
		err->dse_type = DSE_NAMEERROR;
		err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		err->ERR_NAME.DSE_na_matched = dn_cpy (object);
		if (dn != NULLDN)
			dn->dn_parent = dn_tmp;

		return(DS_X500_ERROR);
	}

	return(constructor_dsa_info_aux (object, dn_stack, master, entryptr, err, di_p));
}
Exemplo n.º 4
0
int 
oper_rechain (struct oper_act *on)
{
	struct DSE_referral         * ref = &(on->on_resp.di_error.de_err.ERR_REFERRAL);
	struct continuation_ref     * cref;
	struct chain_arg	* cha = &(on->on_req.dca_charg);
	struct trace_info		* ti;
	struct di_block * ap2di();

	DLOG(log_dsap, LLOG_TRACE, ("Rechain an operation ..."));
	cref = ref->DSE_ref_candidates;

	if(cref == NULLCONTINUATIONREF) {
		LLOG(log_dsap, LLOG_FATAL, ("No continuation reference to rechain"));
		return(NOTOK);
	}

	cha->cha_target = dn_cpy(cref->cr_name);
	cha->cha_progress = cref->cr_progress;
	cha->cha_aliasderef = ((cha->cha_aliasedrdns = cref->cr_aliasedRDNs) != CR_NOALIASEDRDNS);

	if (cha->cha_aliasderef) {
		if ((on->on_arg->dca_dsarg.arg_type == OP_SEARCH)
				&& (on->on_arg->dca_dsarg.arg_sr.sra_subset == SRA_ONELEVEL))
#ifdef COMPAT_6_0
		{
			on->on_arg->dca_dsarg.arg_sr.sra_subset = SRA_BASEOBJECT;
			cha->cha_entryonly = FALSE;
		}
#else
			cha->cha_entryonly = TRUE;
#endif
		else
			cha->cha_entryonly = FALSE;
	}
Exemplo n.º 5
0
int 
consolidate_move (void) {
	if (move_flag) {
		move_flag = FALSE;
		dn_free (fixed_pos);
		fixed_pos = dn_cpy (dn);
	}
}
Exemplo n.º 6
0
struct dn_seq *
dn_seq_cpy (struct dn_seq *dnseq)
{
	struct dn_seq * ptr;
	struct dn_seq * ptr2;
	struct dn_seq * result = NULLDNSEQ;


	for (ptr=dnseq ; ptr!=NULLDNSEQ; ptr=ptr->dns_next ) {
		ptr2 = dn_seq_alloc();
		ptr2 -> dns_next = result;
		result = ptr2;
		result->dns_dn = dn_cpy (ptr->dns_dn);
	}
	return (result);
}
Exemplo n.º 7
0
main()
{
	struct  passwd  *pw_entry ;
	struct  passwd  *getpwuid() ;
	struct	stat	buf ;

	int	i = 1 ;
	int     uid ;
	int	um ;
	char	pass1[LINESIZE] ;
	char	pass2[LINESIZE] ;
	char	Read_in_Stuff[LINESIZE] ;
	char	**vecptr ;
	char 	*tmpdraft ;
	char	home_dir[LINESIZE] ;
	char	*p, *part1, *part2 ;
	char	quipurc_file[100] ;
	char	tailor_file[100] ;
	char	user_name[9] ;
	char	*localptr = Local ;
	char	print_format = EDBOUT ;
	EntryInfo	*ptr ;
	static  CommonArgs ca = default_common_args;
	
	vecptr = (char **) malloc(100) ;
	vecptr[0] = malloc (LINESIZE) ;
	(void) strcpy(vecptr[0], "showentry") ;
	(void) strcpy(pass1, "x") ;
	(void) strcpy(pass2, "y") ;
	tmpdraft = malloc (LINESIZE) ;
	(void) strcpy(tmpdraft, "/tmp/dish-") ;

	if ((opt = ps_alloc (std_open)) == NULLPS)
		fatal (-62, "ps_alloc failed");
	if (std_setup (opt, stderr) == NOTOK)
		fatal (-63, "std_setup failed");
	if ((rps = ps_alloc (std_open)) == NULLPS)
		fatal (-64, "ps_alloc 2 failed");
	if (std_setup (rps, stdout) == NOTOK)
		fatal (-65, "std_setup 2 failed");
	(void) strcpy(filterstring, "userid=") ;

	/* Sort out files, userids etc. */
	uid=getuid() ;
	if ((pw_entry=getpwuid(uid)) == 0)
	{
		ps_printf(rps, "Who are you? (no name for your uid number)\n") ;
		exit(1) ;
	}
	(void) strcpy(user_name, pw_entry->pw_name) ;
	(void) strcat(tmpdraft, user_name) ;

	if (getenv("HOME") == 0) 
	{
		ps_printf(rps, "No home directory?!!") ;
		(void) strcpy(home_dir, pw_entry->pw_dir) ;
	}
	else
	{
		(void) strcpy(home_dir, getenv("HOME")) ;
	}

	(void) strcpy(quipurc_file, home_dir) ;
	(void) strcat(quipurc_file, "/.quipurc") ;

	(void) strcpy(tailor_file, isodefile ("dishinit", 1));

	Manager[0] = 0;
	Password[0] = 0;
	Local[0] = 0;

	(void) stat(tailor_file, &buf) ;
	(void) seteuid(buf.st_uid) ;	/* set effective to enable */
					/* us to read protected file */

	if ((fp_tailor = fopen(tailor_file, "r")) == 0)
	{
		ps_print(rps, "Can't open Tailor File. Abort.\n") ;
		exit(1) ;
	}

	while (fgets (Read_in_Stuff, LINESIZE, fp_tailor) != 0)
	{
		if (!strcmp(Read_in_Stuff, "##Anything after this line is copied into the users ~/.quipurc file\n"))
		{
			break ;
		}

		p = SkipSpace (Read_in_Stuff);
		if (( *p == '#') || (*p == '\0'))
			continue;  		/* ignore comments and blanks */

		part1 = p;
		if ((part2 = index (p,':')) == NULLCP) {
			ps_printf (opt,"Seperator missing '%s'. Ignoring..\n",p);
		}

		*part2++ = '\0';
		part2 = TidyString (part2);

		if (lexequ(part1, "manager") == 0)
		{
			(void) strcpy(Manager, part2) ;
		}
		else
		if (lexequ(part1, "password") == 0)
		{
			(void) strcpy(Password, part2) ;
		}
		else
		if (lexequ(part1, "local") == 0)
		{
			(void) strcpy(Local, part2) ;
		}
		else
		{
			ps_printf(rps, "Error in tailor. What's a %s?\n", part1) ;
		}

	}
	(void) setuid(uid) ;			/* Restore Userid to original user. */

/* create ~/.quipurc file. NB this does eradicate anything in there.
 * 			   (Theoretically nothing.) 
 */

	if (Manager[0] == 0) {
		ps_print(rps, "Can't find out the managers name\n") ;
		exit(1) ;
	}
	if (Password[0] == 0) {
		ps_print(rps, "Can't find out the managers password\n") ;
		exit(1) ;
	}
	if (Local[0] == 0) {
		ps_print(rps, "Can't find out where to search\n") ;
		exit(1) ;
	}

	um = umask(0177) ;
	if ((fp_quipurc = fopen(quipurc_file, "w")) == 0)
	{
		ps_printf(rps, "Can't open ~/.quipurc. Aborting..\n") ;
		exit(1) ;
	}
	(void) umask(um) ;	

	if ((fileps = ps_alloc(std_open)) == NULLPS)
	{
		fatal (-66, "ps_alloc 2 failed");
	}
	if (std_setup (fileps, fp_quipurc) == NOTOK)
	{
		fatal (-67, "std_setup 2 failed");
	}


	/* Sorting out the bind section */
	quipu_syntaxes() ;		/* set up the needed function pointers */
	dsap_init(&i, &vecptr) ;

	(void) strcpy(bindarg.dba_passwd, Password) ;
	bindarg.dba_version = DBA_VERSION_V1988;
	bindarg.dba_passwd_len = strlen(bindarg.dba_passwd) ;

	if ((bindarg.dba_dn = str2dn (Manager)) == NULLDN) 
	{
		ps_printf (opt,"Invalid Manager name %s (???!)\n",Manager) ;
		exit(1) ;
	}

	if (ds_bind (&bindarg, &binderr, &bindresult) != OK)
	{
		ps_printf(rps, "Can't bind as the manager.\n") ;
		exit(1);
	}
	/* Hopefully, should be successfully bound */

/*
 * We now call the search stuff with the right bits, to see if we can get a
 * match of uid='user_name'. Once there, we echo lots of information from
 * their entry out to the .quipurc file.
 * Hopefully there should only be one match. This assumes that ALL dir info
 * up to date, and that SG do not allow multiple users with the same login.
 */

/* set up the appropriate structures and defaults. */

	search_arg.sra_common = ca; /* struct copy */
	search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 2 ;
	search_arg.sra_eis.eis_allattributes = FALSE ;
	search_arg.sra_searchaliases = FALSE;
	search_arg.sra_subset = SRA_ONELEVEL;
	search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES ;
	search_arg.sra_eis.eis_select = NULLATTR ;
	search_arg.sra_eis.eis_allattributes = TRUE ;
	search_arg.sra_filter = filter_alloc() ;
		/* Default filter. */
		search_arg.sra_filter->flt_next = NULLFILTER;
		search_arg.sra_filter->flt_type = FILTER_ITEM;
		search_arg.sra_filter->FUFILT = NULLFILTER;
		

	if (*localptr == '@')
	{
		localptr++;
	}
	if ((search_arg.sra_baseobject = str2dn(localptr)) == NULLDN)
	{
		ps_printf (opt,"Invalid sequence in username %s.\n", localptr);
		exit(1) ;
	}

	(void) strcat(filterstring, user_name) ;

	search_arg.sra_filter->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY ;

	if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = AttrT_new ("userid")) == NULLAttrT)
	{
		ps_printf(rps, "Oops, userid is not a valid attr type. ABORT!!\n") ;
		exit(1) ;
	}
	if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = str2AttrV (user_name, search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->oa_syntax)) == NULLAttrV)
	{
		ps_printf(rps, "%s is not a valid attribute value.\n", user_name) ;
	}

/* call search */
/* We now ought to be in the right place, and with the search stuff set,
 * ready to call search, and receive one (or no) entry back, which then 
 * gets processed accordingly.
 */

	if (ds_search (&search_arg, &search_error, &search_result) != DS_OK)
	{
		ps_printf(rps, "Search failed...\n") ;
		exit (1) ;
		/* This is not the same as coming back with */
		/* message "search failed to find anything. */
	}

/* If the user does not exist in the DIT, print out the limited .quipurc
 * and the warning message, and allow the user to play DISH.
 */

	if (search_result.CSR_entries == NULLENTRYINFO)
	{
		ps_printf(opt, "Unfortunately, you seem to have no entry in\n") ;
		ps_printf(opt, "the directory. Contact '%s' who should be able to help.\n", Manager) ;
		ps_printf(opt, "In the mean time, you can read, but not write.\n") ;
	}
	else
	{
		ptr = search_result.CSR_entries ;
		dn = dn_cpy(ptr->ent_dn) ;	/* Essence of move user_name. */

		/* collect the info and put it into current_entry */

		/* Set up the desired attribute type to be read*/
		/* from read.c */
		if ((at = AttrT_new ("userPassword")) != NULLAttrT) 
		{
			as_flag = as_merge (as_flag, as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO));
		}
		else
		{
			ps_printf(rps, "Oops, Serious error. unknown attribute type 'userPassword'.\n") ;
			exit(1) ;
		}

		if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY)
		{	
			read_arg.rda_common = ca; /* struct copy */
			read_arg.rda_object = dn;
			read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
			read_arg.rda_eis.eis_allattributes = TRUE ;
			read_arg.rda_eis.eis_select = NULLATTR ;

			if (ds_read (&read_arg, &read_error, &read_result) != DS_OK)
			{
				ps_printf(rps, "We even seem to be having problems reading\n" ) ;
				ps_printf(rps, "an entry we searched and found!! HELP!!\n") ;
				exit(1) ;
			}
			if (read_result.rdr_entry.ent_attr == NULLATTR)
			{
				ps_printf(rps, "No attributes present. Even though\n") ;
				ps_printf(rps, "we found you by userid attribute!!! HELP!!\n") ;
				exit (1) ;
			}
			cache_entry (&(read_result.rdr_entry), read_arg.rda_eis.eis_allattributes, TRUE) ;
		}

		if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY)
		{
			ps_printf(rps, "We still have nothing.Even after reading? Abort.\n") ;
			exit(1) ;
		}

		ps_printf(fileps, "username: "******"\n") ;

		ps_printf(fileps, "me: ") ;
		dn_print(fileps, dn, EDBOUT) ;
		ps_printf(fileps, "\n") ;

		/* now showattribute -nokey to display it. */

		ps_printf(fileps, "password: "******"You need a password...\n") ;
				(void) strcpy(pass1, getpassword("Enter Password: "******"Re-enter password: "******"\nMismatch - Try again.\n") ;
				}
			}
			ps_printf(fileps, "%s\n", pass1) ;

			um = umask(0177) ;
			if ((fp_draft = fopen(tmpdraft, "w")) == 0)
			{
				ps_print(rps, "Can't open draft file... Abort.\n") ;
				exit(1) ;
			}
			(void) umask(um) ;

			(void) fprintf(fp_draft, "UserPassword = %s\n", pass1) ;
		 	(void) fprintf(fp_draft, "acl = self # write # attributes # acl $ userPassword\n") ;
			(void) fprintf(fp_draft, "acl = others # compare # attributes # acl $ userPassword\n\n") ;
			(void) fclose(fp_draft) ;

			if ((fp_draft = fopen (tmpdraft, "r")) == NULL) {
				ps_printf (opt, "Can't open draft entry %s\n", tmpdraft);
				exit(1) ;
			}

			entry_ptr = get_default_entry (NULLENTRY);
#ifdef TURBO_DISK
			entry_ptr->e_attributes = fget_attributes (fp_draft);
#else
			entry_ptr->e_attributes = get_attributes (fp_draft);
#endif

			(void) fclose (fp_draft);

			mod_arg.mea_common = ca; /* struct copy */
			mod_arg.mea_object = dn;
			for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent)
				;
			entry_ptr->e_name = rdn_cpy (moddn->dn_rdn);
	
			/* add rdn as attribute */
			avst = avs_comp_new (AttrV_cpy (&entry_ptr->e_name->rdn_av));
			temp = as_comp_new (AttrT_cpy (entry_ptr->e_name->rdn_at), avst, NULLACL_INFO);
			entry_ptr->e_attributes = as_merge (entry_ptr->e_attributes, temp);

			for (as = entry_ptr->e_attributes; as != NULLATTR; as = as->attr_link)
			{
				emnew = NULLMOD;
				trail = as->attr_link;
				as->attr_link = NULLATTR;
				temp = current_entry->e_attributes;
				for (; temp != NULLATTR; temp = temp->attr_link) 
					if (AttrT_cmp (as->attr_type, temp->attr_type) == 0)
					{
						/* found it - does it need changing ? */
						if (avs_cmp (as->attr_value, temp->attr_value) != 0) 
							emnew = modify_avs (as->attr_value, temp->attr_value,as->attr_type);
						break;
					}

				if (temp == NULLATTR) 
				{
					emnew = em_alloc ();
					emnew->em_type = EM_ADDATTRIBUTE;
					emnew->em_what = as_cpy(as);
					emnew->em_next = NULLMOD;
				}
				if (emnew != NULLMOD)
				{
					mod_arg.mea_changes = ems_append (mod_arg.mea_changes,emnew);
				}
				as->attr_link = trail;
			}

			while (ds_modifyentry (&mod_arg, &mod_error) != DS_OK)
			{
				if (dish_error (opt, &mod_error) == 0)
				{
					ps_printf(rps,"We have a dish error. Bye.\n") ;
					entry_free (entry_ptr);
					exit(1) ;
				}
				mod_arg.mea_object = mod_error.ERR_REFERRAL.DSE_ref_candidates->cr_name;
			}
			ps_print (rps, "Modified ");
			dn_print (rps, dn, EDBOUT);
			ps_print (rps, "\n");
			delete_cache (dn);	/* re-cache when next read */

			entry_free (entry_ptr);
			ems_part_free (mod_arg.mea_changes);
		}
	}

	while(fgets(Read_in_Stuff, LINESIZE, fp_tailor) != 0)
	{
		fputs(Read_in_Stuff, fp_quipurc) ;
	}
		
	(void) fclose(fp_quipurc) ;	
	(void) fclose(fp_tailor) ;

/*	(void) fprintf(fp_quipurc, "dsap: local_dit \"%s\"\n", Local) ;
	(void) fprintf(fp_quipurc, "notype: acl\n") ;
	(void) fprintf(fp_quipurc, "notype: treestructure\n") ;
	(void) fprintf(fp_quipurc, "notype: masterdsa\n") ;
	(void) fprintf(fp_quipurc, "notype: slavedsa\n") ;
	(void) fprintf(fp_quipurc, "notype: objectclass\n") ;
	(void) fprintf(fp_quipurc, "cache_time: 30\n") ;
	(void) fprintf(fp_quipurc, "connect_time: 2\n") ;
 */
	(void) ds_unbind() ;
	(void) unlink(tmpdraft) ;
}
Exemplo n.º 8
0
int 
find_entry (DN object, common_args *ca, DN acl_who, struct dn_seq *dn_stack, int master, Entry *ent_p, struct DSError *err, struct di_block **di_p, int optype)
{
	int deref = FALSE;
	extern time_t cache_timeout;
	DN dn_found;
	int res;

	DLOG (log_dsap,LLOG_TRACE,("find_entry"));
	err->dse_type = DSE_NOERROR;

	if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0)
		deref = TRUE;

	if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0)
		master = TRUE;

	switch(really_find_entry(object,deref,dn_stack,master,ent_p,err,di_p)) {
	case DS_OK:
		DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: OK"));
		/* Have set up ent_p continue processing */
		break;

	case DS_CONTINUE:
		DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: CONT"));
#ifdef DEBUG
		di_list_log((*di_p));
#endif
		/* Have set up di_blocks of DSAs to be questioned */
		return(DS_CONTINUE);

	case DS_X500_ERROR:
		DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: X500_ERROR"));
		/* Have set up an error */
		return(DS_X500_ERROR);

	default:
		/* Scream */
		LLOG(log_dsap, LLOG_EXCEPTIONS, ("really_find_entry failed in find_entry 1"));
		return(DS_ERROR_LOCAL);
	}

	dn_found = get_copy_dn (*ent_p);

	/* if the returned entry is a CONSTRUCTOR, return a referral */
	if ((*ent_p)->e_data == E_TYPE_CONSTRUCTOR) {
		DLOG(log_dsap, LLOG_DEBUG, ("find_entry - constructor"));
		res = constructor_dsa_info(dn_found,dn_stack,FALSE,(*ent_p),err,di_p);
		dn_free (dn_found);
		return (res);
	}

	/* if the returned entry is a COPY, - check service controls */
	if (((*ent_p)->e_data != E_DATA_MASTER) && (master)) {

		/* DSAs are special for read/modify */
		if ((optype == OP_READ) ||
				(optype == OP_MODIFYRDN) ||
				(optype == OP_MODIFYENTRY)) {
			if ((quipu_ctx_supported (*ent_p) > 2) && (quipu_version_7 (*ent_p))) {
				if (dn_cmp (dn_found, mydsadn) == 0)
					goto out;
mk_ref:
				;
				(*di_p) = di_alloc();
				(*di_p)->di_type = DI_TASK;
				(*di_p)->di_dn = dn_found;
				(*di_p)->di_target = dn_cpy(dn_found);
				(*di_p)->di_reftype = RT_UNDEFINED;
				(*di_p)->di_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED;
				(*di_p)->di_aliasedRDNs = CR_NOALIASEDRDNS;
				(*di_p)->di_entry = *ent_p;
				(*ent_p)->e_refcount++;
				(*di_p)->di_state = DI_COMPLETE;
				return DS_CONTINUE;
			}
		}

		DLOG(log_dsap, LLOG_DEBUG, ("find_entry - slave master needed"));
		res = constructor_dsa_info(dn_found,dn_stack,TRUE,(*ent_p),err,di_p);
		dn_free (dn_found);
		return (res);

	} else if ( ((optype == OP_MODIFYRDN) || (optype == OP_MODIFYENTRY)) &&
				(quipu_ctx_supported (*ent_p) > 2) &&
				quipu_version_7 (*ent_p) &&
				(dn_cmp (dn_found, mydsadn) != 0))
		goto mk_ref;

#ifdef WRONG_BEHAVIOUR

	/* if this is right, we need to make sure that dsa_info */
	/* pick ups the correct external reference */

	if ((*ent_p)->e_external &&
			((*ent_p)->e_reftype != RT_NONSPECIFICSUBORDINATE)) {
		res = constructor_dsa_info(dn_found,dn_stack,TRUE,(*ent_p),err,di_p);
		dn_free (dn_found);
		return (res);
	}
#endif

	if (((*ent_p)->e_data == E_TYPE_CACHE_FROM_MASTER) &&
			(timenow - (*ent_p)->e_age > cache_timeout)) {
		DLOG(log_dsap, LLOG_DEBUG, ("find_entry - cache timed out"));
		res = constructor_dsa_info(dn_found,dn_stack,TRUE,(*ent_p),err,di_p);
		delete_cache (dn_found);
		dn_free (dn_found);
		return (res);
	}

out:
	;
	dn_free (dn_found);

	if ((*ent_p)->e_parent == NULLENTRY) {
		DLOG(log_dsap, LLOG_DEBUG, ("find_entry: (*ent_p)->e_parent is NULLENTRY"));
		return (DS_OK);     /* no acl for root entry */
	}

	if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_parent->e_acl->ac_child, object) == NOTOK) {
		err->dse_type = DSE_SECURITYERROR;
		err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
		return (DS_X500_ERROR);
	}

	if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_acl->ac_entry, object) == NOTOK) {
		err->dse_type = DSE_SECURITYERROR;
		err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
		return (DS_X500_ERROR);
	}

	return (DS_OK);
}
Exemplo n.º 9
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 */
}
Exemplo n.º 10
0
int 
move (char *arg)
{
	extern int print_parse_errors;

	DN              user_down ();
	DN              str2dn_aux ();
	DN		sequence_dn();
	DN              tmpdn;
	char *		ptr;
	char		alias = FALSE;
	int		len;

	print_parse_errors = FALSE;

	if (*arg == '-') {
		print_parse_errors = TRUE;
		return (NOTOK);	   /* can't be a move if it starts with a minus */
	}

	if (*arg == '+')
		arg++;  /* old style call */

	ptr = arg;
	while (*ptr != 0) {
		if (! isdigit (*ptr))
			break;
		ptr++;
	}

	if (*ptr == 0) {
		/* sequence move */
		dn_free (dn);
		dn = dn_cpy (sequence_dn(atoi(arg)));
		print_parse_errors = TRUE;
		if (dn == NULLDN) {
			ps_printf (OPT,"Invalid sequence number %s\n",arg);
			return (NOTOK);
		} else
			return (OK);
	}

	len = strlen(arg);
	if ((arg[0] == '<') && ( arg[len-1] == '>')) {
		dn_free(dn);
		dn = str2dn(arg);
		return (OK);
	}

	if ((ptr = index (arg,'@')) != NULLCP) {
		*ptr = 0;

		if (*arg == 0) {
			/* from root */
			dn_free (dn);
			dn = NULLDN;
			*ptr ='@';
			arg = ++ptr;
			if (*arg == 0) {
				print_parse_errors = TRUE;
				return (OK);    /* @ -> move to root */
			}
			if ((ptr = index (arg,'@')) != NULLCP)
				*ptr = 0;
		}
	} else {
		dn_free (dn);
		dn = dn_cpy (fixed_pos);
	}

	if (strcmp (arg,"..") == 0) {
		do {
			DN              dnptr;
			DN              trail;

			if (dn == NULLDN) {
				print_parse_errors = TRUE;
				ps_print (OPT, "Can't go back past root\n");
				return (NOTOK);
			}
			if (dn->dn_parent == NULLDN) {
				dn_free (dn);
				dn = NULLDN;
			} else {
				for (dnptr = dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent)
					trail = dnptr;

				dn_comp_free (dnptr);
				trail->dn_parent = NULLDN;
			}
			if  (ptr == NULLCP) {
				print_parse_errors = TRUE;
				return (OK);
			}
			arg = ++ptr;
			if ((ptr = index (arg,'@')) != NULLCP)
				*ptr = 0;
		} while (strcmp (arg,"..") == 0);
	}

	if (ptr != NULL)
		*ptr = '@';

	if ((tmpdn = str2dn_aux (arg,&alias)) != NULLDN) {
		if (dn == NULLDN)
			dn = tmpdn;
		else {
			if (alias) {
				dn_free (dn);
				dn = tmpdn;
			} else
				dn_append (dn,tmpdn);
		}
		print_parse_errors = TRUE;
		return (OK);
	} else {
		print_parse_errors = TRUE;
		return (NOTOK);
	}

}
Exemplo n.º 11
0
int 
set_current_pos (void) {
	move_flag = FALSE;
	dn_free (dn);
	dn = dn_cpy (fixed_pos);
}
Exemplo n.º 12
0
int 
call_showentry (int argc, char **argv)
{
	Attr_Sequence   eptr;
	char           *vect[2];
	int             x;
	extern char	name_flag;
	extern char	all_flag;
	extern Attr_Sequence as_flag;
	extern char	flag_show;
	char            full_edb_flag;
	char            *temp_file_name;
	extern int      mod_template();

	vect[0] = "showentry";

	move_flag = FALSE;
	fred_flag = FALSE;
	fred_expand = FALSE;
	fred_list = FALSE;
	fred_long = 2;
	fred_phone = FALSE;
	fred_photo = FALSE;
	fred_sequence = TRUE;
	fred_subdisplay = FALSE;
	name_flag = FALSE;
	full_edb_flag = FALSE;

	for (x=1; x<argc; x++) {
		if (test_arg (argv[x], "-move",2))
			move_flag = TRUE;
		else if (test_arg (argv[x], "-nomove",3))
			move_flag = FALSE;
		else if (test_arg (argv[x], "-fred",4))
			fred_flag = TRUE;
		else if (test_arg (argv[x], "-expand",4))
			fred_expand = TRUE;
		else if (test_arg (argv[x], "-fredlist",8))
			fred_list = TRUE;
		else if (test_arg (argv[x], "-full",4))
			fred_long = TRUE;
		else if (test_arg (argv[x], "-summary",7))
			fred_long = FALSE;
		else if (test_arg (argv[x], "-phone",5))
			fred_phone = TRUE;
		else if (test_arg (argv[x], "-fredphoto",9))
			fred_photo = dad_flag;
		else if (test_arg (argv[x], "-nofredseq",9))
			fred_sequence = FALSE;
		else if (test_arg (argv[x], "-subdisplay",10))
			fred_subdisplay = TRUE;
		else if (test_arg (argv[x], "-fedb",4)) {
			if (x + 1 == argc) {
				ps_printf (opt, "We need a filename for the full edb entry.\n");
				return;
			} else {
				shuffle_up (argc, argv, x);
				argc--;
				if (*(temp_file_name = argv[x]) != '/') {
					ps_printf (opt, "We need a real file spec for the file name.\n");
					return;
				}
			}
			full_edb_flag = TRUE;
		} else
			continue;
		shuffle_up (argc--,argv,x--);

	}
	if ((argc = read_cache (argc, argv)) < 0)
		return;


	if (argc != 1) {
		ps_printf (OPT,"Unknown option %s\n",argv[1]);
		Usage (argv[0]);
		return;
	}

	if (current_entry == NULLENTRY) {
		ps_print (OPT,"Specify an entry \n");
		/* this CAN happen - when the entry is not cache, but -noread */
		return;
	}
	if (full_edb_flag) {
		 mod_template(temp_file_name,0);
		return;
	}

	if (fred_flag) {
		if (fred_long == 2)
			if ((fred_subdisplay && fred_expand)
					|| (!fred_subdisplay && !fred_expand))
				fred_long = TRUE;
			else
				fred_long = fred_expand;
		if (fred_expand)
			fred_long = fred_subdisplay = TRUE;

		if (fred_list
				&& frompipe
				&& rps -> ps_byteno == 0
				&& opt -> ps_byteno == 0) {
			DN	new_dn = dn_cpy (current_dn);

			showfredDNs (new_dn, fred_long);
			dn_free (new_dn);
		}

		 showfred (current_dn, fred_long, fred_subdisplay);
	} else {
		if (name_flag) {
			dn_print (RPS,dn,EDBOUT);
			ps_print (RPS,"\n");
		}

		if (all_flag)
			eptr = current_entry->e_attributes;
		else
			eptr = as_flag;

		if (flag_show)
			for (; eptr != NULLATTR; eptr = eptr->attr_link)
				showattribute (eptr->attr_type);
	}

	consolidate_move();
}
Exemplo n.º 13
0
int 
do_ds_read (struct ds_read_arg *arg, struct DSError *error, struct ds_read_result *result, DN binddn, DN target, struct di_block **di_p, int dsp, int quipu_ctx, int authtype)
{
	Entry  entryptr;
	int retval;
#ifdef NOTUSED
	int authenticated;
#endif
	DN realtarget;
	char authp;

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

	if (!dsp)
		target = arg->rda_object;

	if (!dsp && dsa_read_control(arg,result))
		return (DS_OK);

	if (target == NULLDN) {
		/* can't read from the root */
		error->dse_type = DSE_NAMEERROR;
		error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
		error->ERR_NAME.DSE_na_matched = NULLDN;
		return (DS_ERROR_REMOTE);
	}

	switch(find_entry(target,&(arg->rda_common),binddn,NULLDNSEQ,FALSE,&(entryptr), error, di_p, OP_READ)) {
	case DS_OK:
		/* Filled out entryptr - carry on */
		break;
	case DS_CONTINUE:
		/* Filled out di_p - what do we do with it ?? */
		return(DS_CONTINUE);

	case DS_X500_ERROR:
		/* Filled out error - what do we do with it ?? */
		return(DS_X500_ERROR);
	default:
		/* SCREAM */
		LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_read() - find_entry failed"));
		return(DS_ERROR_LOCAL);
	}

	realtarget = get_copy_dn (entryptr);

	/* User can be authenticated by using strong authentication for this
	 * operation, or by using the credntials from the bind.
	 */

	if (!manager(binddn))
		authp = entryptr->e_authp ? entryptr->e_authp->ap_readandcompare
				: AP_SIMPLE;
	else
		authp = AP_SIMPLE;

#ifdef NOTUSED
	authenticated = 0;

	/* Credentials provided in the ds_bind */
	if ((bind_policy & POLICY_ACCESS_READ) && (!dsp) && (binddn != NULLDN))
		authenticated = 1;
#endif

	/* Strong authentication  */
	/* If it's there, check it, even if you won't believe it anyway */
	if ((retval = check_security_parms((caddr_t) arg,
									   _ZReadArgumentDataDAS,
									   &_ZDAS_mod,
									   arg->rda_common.ca_security,
									   arg->rda_common.ca_sig, &binddn)) != 0) {
		error->dse_type = DSE_SECURITYERROR;
		error->ERR_SECURITY.DSE_sc_problem = retval;
		dn_free (realtarget);
		return (DS_ERROR_REMOTE);
	}

#ifdef NOTUSED
	if ((strong_policy & POLICY_ACCESS_READ) &&
			(arg->rda_common.ca_sig != (struct signature *) 0))
		authenticated = 1;
#endif

	/* entry has got a full list of attributes,  eventually
	   select one required */
	if (check_acl ((authtype % 3) >= authp ? binddn : NULLDN, ACL_READ,
				   entryptr->e_acl->ac_entry, realtarget) == NOTOK) {
		if (dsp && (check_acl (binddn,ACL_READ,entryptr->e_acl->ac_entry, realtarget) == OK)) {
			error->dse_type = DSE_SECURITYERROR;
			error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION;
			dn_free (realtarget);
			return (DS_ERROR_REMOTE);
		} else {
			error->dse_type = DSE_SECURITYERROR;
			error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
			dn_free (realtarget);
			return (DS_ERROR_REMOTE);
		}
	}

	if (entryptr->e_dsainfo && need_pseudo_dsa(entryptr,arg)) {

		/* Its a 7.0 or better DSA.
		 * pseudo attributes asked for.
		 * special routing req'd
		         */

		if (dn_cmp (realtarget, mydsadn) == 0) {
			/* Its me - generate result */

			if ((result->rdr_entry.ent_attr = dsa_eis_select (
												  arg->rda_eis,entryptr, dsp ? NULLDN : binddn,
												  quipu_ctx, realtarget)) != NULLATTR)
				goto out;

			if ( arg->rda_eis.eis_allattributes || arg->rda_eis.eis_select == NULLATTR)
				goto out;

			error->dse_type = DSE_ATTRIBUTEERROR;
			error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (entryptr);
			error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE;
			error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy(arg->rda_eis.eis_select->attr_type);
			error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV;
			error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM;
			dn_free (realtarget);
			return (DS_ERROR_REMOTE);

		} else {
			/* make referral to DSA in this entry */
			(*di_p) = di_alloc();
			(*di_p)->di_type = DI_TASK;
			(*di_p)->di_dn = realtarget;
			(*di_p)->di_target = dn_cpy(realtarget);
			(*di_p)->di_reftype = RT_UNDEFINED;
			(*di_p)->di_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED;
			(*di_p)->di_aliasedRDNs = CR_NOALIASEDRDNS;
			(*di_p)->di_entry = entryptr;
			entryptr->e_refcount++;
			(*di_p)->di_state = DI_COMPLETE;

			return DS_CONTINUE;
		}

	}

	if (cant_use_cache (entryptr,binddn,arg->rda_eis,realtarget)) {
		int res =  referral_dsa_info(realtarget,NULLDNSEQ,FALSE,entryptr,error,di_p,
									 arg->rda_common.ca_servicecontrol.svc_options & SVC_OPT_PREFERCHAIN);
		dn_free (realtarget);
		return res;
	}

	if (dsp && (eis_check (arg->rda_eis,entryptr, binddn) != OK)) {
		/* Can only send public things over DSP - but user is entitled to more */
		error->dse_type = DSE_SECURITYERROR;
		error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION;
		dn_free (realtarget);
		return (DS_ERROR_REMOTE);
	}

	if ((result->rdr_entry.ent_attr = eis_select (arg->rda_eis,entryptr, dsp ? NULLDN : binddn, quipu_ctx, realtarget)) == NULLATTR)
		if ( !arg->rda_eis.eis_allattributes && arg->rda_eis.eis_select != NULLATTR) {
			error->dse_type = DSE_ATTRIBUTEERROR;
			error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (entryptr);
			error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE;
			error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy(arg->rda_eis.eis_select->attr_type);
			error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV;
			error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM;
			dn_free (realtarget);
			return (DS_ERROR_REMOTE);
		}

out:
	;
	result->rdr_entry.ent_dn = realtarget;
	result->rdr_entry.ent_iscopy = entryptr->e_data;
	result->rdr_entry.ent_age = (time_t) 0;
	result->rdr_entry.ent_next = NULLENTRYINFO;
	result->rdr_common.cr_requestor = NULLDN;
	/* if no error and NOT SVC_OPT_DONTDEREFERENCEALIASES then */
	/* the alias will have been derefeferenced -signified by   */
	/* NO_ERROR !!! */
	result->rdr_common.cr_aliasdereferenced = (error->dse_type == DSE_NOERROR) ? FALSE : TRUE;
	return (DS_OK);

}
Exemplo n.º 14
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);
	}
}
Exemplo n.º 15
0
struct connection *
make_conn_block (DN name, struct PSAPaddr *addr, int conn_ctx)
{
	struct connection	* cn;

	struct TSAPaddr *ta;
	struct NSAPaddr *na;
	extern struct PSAPaddr * mydsaaddr;
	int x;
	char onnet = FALSE;

	/*
	* Set up a new connection block and add it to the list.
	*/

	if(dn_cmp(name, mydsadn) == 0) {
		LLOG(log_dsap, LLOG_FATAL, ("Trying to connect to self :-)"));
		return(NULLCONN);
	}

	if (! addr) {
		pslog (log_dsap,LLOG_EXCEPTIONS,"Invalid (accesspoint) reference",
			   (IFP)dn_print,(caddr_t)name);
		return(NULLCONN);
	}

	/* see if on the appropriate net */
	ta = & (addr->pa_addr.sa_addr);

	/* compare ta and ts_communities to see if they have a network in common */
	for (na=ta->ta_addrs , x = ta->ta_naddr - 1 ;
			x >= 0;
			na++, x-- ) {

		int *ip;

		for (ip = ts_communities; *ip; ip++) {
			if (na->na_community == *ip) {
				onnet = TRUE;
				break;
			}
		}
	}

	if (! onnet) {
		LLOG(log_dsap, LLOG_TRACE, ("make_conn_block - no network in common"));
		return(NULLCONN);
	}

	if((cn = conn_alloc()) == NULLCONN) {
		LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_conn_block - conn_alloc() out of memory"));
		return(NULLCONN);
	}
	cn->cn_state = CN_WAITING;
	cn->cn_ctx = conn_ctx;
	cn->cn_initiator = TRUE;
	make_dsa_bind_arg(&(cn->cn_connect.cc_req));

	cn->cn_dn = dn_cpy(name);
	DLOG (log_dsap,LLOG_TRACE,( "Before psap_dup: %s", paddr2str(addr,NULLNA)));
	psap_dup(&(cn->cn_addr), addr);
	DLOG (log_dsap,LLOG_TRACE,( "After psap_dup:  %s", paddr2str(&(cn->cn_addr),NULLNA)));

	return(cn);
}