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)); }
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; }
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)); }
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; }
int consolidate_move (void) { if (move_flag) { move_flag = FALSE; dn_free (fixed_pos); fixed_pos = dn_cpy (dn); } }
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); }
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) ; }
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); }
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 */ }
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); } }
int set_current_pos (void) { move_flag = FALSE; dn_free (dn); dn = dn_cpy (fixed_pos); }
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(); }
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); }
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); } }
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); }