int ncp_nsrename(struct ncp_conn *conn, int volume, int ns, int oldtype, struct ncp_nlstables *nt, nwdirent fdir, char *old_name, int oldlen, nwdirent tdir, char *new_name, int newlen, struct thread *td, struct ucred *cred) { struct ncp_rq *rqp; int error; error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 4); mb_put_uint8(&rqp->rq, ns); mb_put_uint8(&rqp->rq, 1); /* RRenameToMySelf */ mb_put_uint16le(&rqp->rq, oldtype); /* source Handle Path */ mb_put_uint8(&rqp->rq, volume); mb_put_mem(&rqp->rq, (c_caddr_t)&fdir, sizeof(fdir), MB_MSYSTEM); mb_put_uint8(&rqp->rq, 1); mb_put_uint8(&rqp->rq, 1); /* 1 source component */ /* dest Handle Path */ mb_put_uint8(&rqp->rq, volume); mb_put_mem(&rqp->rq, (c_caddr_t)&tdir, sizeof(tdir), MB_MSYSTEM); mb_put_uint8(&rqp->rq, 1); mb_put_uint8(&rqp->rq, 1); /* 1 destination component */ ncp_rq_pathstring(rqp, oldlen, old_name, nt); ncp_rq_pathstring(rqp, newlen, new_name, nt); error = ncp_request(rqp); if (!error) ncp_rq_done(rqp); return error; }
int ncp_initsearch(struct vnode *dvp, struct thread *td, struct ucred *cred) { struct nwmount *nmp = VTONWFS(dvp); struct ncp_conn *conn = NWFSTOCONN(nmp); struct nwnode *np = VTONW(dvp); struct ncp_rq *rqp; u_int8_t volnum = nmp->n_volume; u_int32_t dirent = np->n_fid.f_id; int error; NCPNDEBUG("vol=%d,dir=%d\n", volnum, dirent); error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 2); /* subfunction */ mb_put_uint8(&rqp->rq, nmp->name_space); mb_put_uint8(&rqp->rq, 0); /* reserved */ ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL); rqp->nr_minrplen = sizeof(np->n_seq); error = ncp_request(rqp); if (error) return error; md_get_mem(&rqp->rp, (caddr_t)&np->n_seq, sizeof(np->n_seq), MB_MSYSTEM); ncp_rq_done(rqp); return 0; }
int ncp_change_obj_passwd(NWCONN_HANDLE connid, const struct ncp_bindery_object *object, const u_char *key, const u_char *oldpasswd, const u_char *newpasswd) { long id = htonl(object->object_id); u_char cryptkey[8]; u_char newpwd[16]; /* new passwd as stored by server */ u_char oldpwd[16]; /* old passwd as stored by server */ u_char len; DECLARE_RQ; memcpy(cryptkey, key, 8); nw_keyhash((u_char *)&id, oldpasswd, strlen(oldpasswd), oldpwd); nw_keyhash((u_char *)&id, newpasswd, strlen(newpasswd), newpwd); nw_encrypt(cryptkey, oldpwd, cryptkey); nw_passencrypt(oldpwd, newpwd, newpwd); nw_passencrypt(oldpwd + 8, newpwd + 8, newpwd + 8); if ((len = strlen(newpasswd)) > 63) { len = 63; } len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40; ncp_init_request_s(conn, 75); ncp_add_mem(conn, cryptkey, 8); ncp_add_word_hl(conn, object->object_type); ncp_add_pstring(conn, object->object_name); ncp_add_byte(conn, len); ncp_add_mem(conn, newpwd, 16); return ncp_request(connid, 23, conn); }
/* * Returns information for a (one-component) name relative to the specified * directory. */ int ncp_obtain_info(struct nwmount *nmp, u_int32_t dirent, int namelen, char *path, struct nw_entry_info *target, struct thread *td,struct ucred *cred) { struct ncp_conn *conn=NWFSTOCONN(nmp); struct ncp_rq *rqp; int error; u_char volnum = nmp->n_volume, ns; if (target == NULL) { NCPFATAL("target == NULL\n"); return EINVAL; } ns = (path == NULL || path[0] == 0) ? NW_NS_DOS : nmp->name_space; error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 6); /* subfunction */ mb_put_uint8(&rqp->rq, ns); mb_put_uint8(&rqp->rq, ns); /* DestNameSpace */ mb_put_uint16le(&rqp->rq, 0xff); /* get all */ mb_put_uint32le(&rqp->rq, IM_ALL); ncp_rq_dbase_path(rqp, volnum, dirent, namelen, path, &nmp->m.nls); error = ncp_request(rqp); if (error) return error; error = ncp_extract_file_info(nmp, rqp, target, path != NULL); ncp_rq_done(rqp); return error; }
static int __P(sncp_request(struct proc *p, struct sncp_request_args *uap)){ int error = 0, rqsize; struct ncp_conn *conn; struct ncp_handle *handle; DECLARE_RQ; error = ncp_conn_findhandle(uap->connHandle,p,&handle); if (error) return error; conn = handle->nh_conn; if (uap->fn == NCP_CONN) return ncp_conn_handler(p, uap, conn, handle); error = copyin(&uap->ncpbuf->rqsize, &rqsize, sizeof(int)); if (error) return(error); error = ncp_conn_lock(conn,p,p->p_ucred,NCPM_EXECUTE); if (error) return(error); ncp_rq_head(rqp,NCP_REQUEST,uap->fn,p,p->p_ucred); if (rqsize) error = ncp_rq_usermem(rqp,(caddr_t)uap->ncpbuf->packet, rqsize); if (!error) { error = ncp_request(conn, rqp); if (error == 0 && rqp->rpsize) ncp_rp_usermem(rqp, (caddr_t)uap->ncpbuf->packet, rqp->rpsize); copyout(&rqp->cs, &uap->ncpbuf->cs, sizeof(rqp->cs)); copyout(&rqp->cc, &uap->ncpbuf->cc, sizeof(rqp->cc)); copyout(&rqp->rpsize, &uap->ncpbuf->rpsize, sizeof(rqp->rpsize)); } ncp_rq_done(rqp); ncp_conn_unlock(conn,p); return error; }
int ncp_conn_frag_rq(struct ncp_conn *conn, struct proc *p, struct ncp_conn_frag *nfp){ int error = 0, i, rpsize; u_int32_t fsize; NW_FRAGMENT *fp; DECLARE_RQ; ncp_rq_head(rqp,NCP_REQUEST,nfp->fn,p,p->p_ucred); if (nfp->rqfcnt) { for(fp = nfp->rqf, i = 0; i < nfp->rqfcnt; i++, fp++) { checkbad(ncp_rq_usermem(rqp,(caddr_t)fp->fragAddress, fp->fragSize)); } } checkbad(ncp_request(conn, rqp)); rpsize = rqp->rpsize; if (rpsize && nfp->rpfcnt) { for(fp = nfp->rpf, i = 0; i < nfp->rpfcnt; i++, fp++) { checkbad(copyin(&fp->fragSize, &fsize, sizeof (fsize))); fsize = min(fsize, rpsize); checkbad(ncp_rp_usermem(rqp,(caddr_t)fp->fragAddress, fsize)); rpsize -= fsize; checkbad(copyout(&fsize, &fp->fragSize, sizeof (fsize))); } } nfp->cs = rqp->cs; nfp->cc = rqp->cc; NCP_RQ_EXIT; return error; }
static NWCCODE ncp_clear_release_physical_record32(NWCONN_HANDLE conn, const char fh[6], u_int32_t startOffset, u_int32_t length, int release) { NWCCODE err; ncp_init_request(conn); ncp_add_mem(conn, fh, 6); ncp_add_dword_hl(conn, startOffset); ncp_add_dword_hl(conn, length); if (release) { err = ncp_request(conn, 28); } else { err = ncp_request(conn, 30); } ncp_unlock_conn(conn); return err; }
int ncp_search_for_file_or_subdir(struct nwmount *nmp, struct nw_search_seq *seq, struct nw_entry_info *target, struct thread *td,struct ucred *cred) { struct ncp_conn *conn = NWFSTOCONN(nmp); struct ncp_rq *rqp; int error; error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 3); /* subfunction */ mb_put_uint8(&rqp->rq, nmp->name_space); mb_put_uint8(&rqp->rq, 0); /* data stream */ mb_put_uint16le(&rqp->rq, 0xffff); /* Search attribs */ mb_put_uint32le(&rqp->rq, IM_ALL); /* return info mask */ mb_put_mem(&rqp->rq, (caddr_t)seq, 9, MB_MSYSTEM); mb_put_uint8(&rqp->rq, 2); /* 2 byte pattern */ mb_put_uint8(&rqp->rq, 0xff); /* following is a wildcard */ mb_put_uint8(&rqp->rq, '*'); rqp->nr_minrplen = sizeof(*seq) + 1 + NCP_INFOSZ + 1; error = ncp_request(rqp); if (error) return error; md_get_mem(&rqp->rp, (caddr_t)seq, sizeof(*seq), MB_MSYSTEM); md_get_uint8(&rqp->rp, NULL); /* skip */ error = ncp_extract_file_info(nmp, rqp, target, 1); ncp_rq_done(rqp); return error; }
int ncp_modify_file_or_subdir_dos_info(struct nwmount *nmp, struct vnode *vp, u_int32_t info_mask, struct nw_modify_dos_info *info, struct thread *td,struct ucred *cred) { struct nwnode *np=VTONW(vp); struct ncp_rq *rqp; u_int8_t volnum = nmp->n_volume; u_int32_t dirent = np->n_fid.f_id; struct ncp_conn *conn=NWFSTOCONN(nmp); int error; error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 7); /* subfunction */ mb_put_uint8(&rqp->rq, nmp->name_space); mb_put_uint8(&rqp->rq, 0); /* reserved */ mb_put_uint16le(&rqp->rq, SA_ALL); /* search attribs: all */ mb_put_uint32le(&rqp->rq, info_mask); mb_put_mem(&rqp->rq, (caddr_t)info, sizeof(*info), MB_MSYSTEM); ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL); error = ncp_request(rqp); if (!error) ncp_rq_done(rqp); return error; }
static NWCCODE ncp_log_physical_record32(NWCONN_HANDLE conn, const char fh[6], u_int32_t startOffset, u_int32_t length, unsigned int flags, unsigned int timeout) { NWCCODE err; ncp_init_request(conn); ncp_add_byte(conn, flags); ncp_add_mem(conn, fh, 6); ncp_add_dword_hl(conn, startOffset); ncp_add_dword_hl(conn, length); ncp_add_word_hl(conn, timeout); err = ncp_request(conn, 109); ncp_unlock_conn(conn); return err; }
/* * target is a 8-byte buffer */ int ncp_get_encryption_key(NWCONN_HANDLE cH, char *target) { int error; DECLARE_RQ; ncp_init_request_s(conn, 23); error = ncp_request(cH, 23, conn); if (error) return error; if (conn->rpsize < 8) return EACCES; memcpy(target, ncp_reply_data(conn, 0), 8); return 0; }
/* * If both dir and name are NULL, then in target there's already a looked-up * entry that wants to be opened. */ int ncp_open_create_file_or_subdir(struct nwmount *nmp,struct vnode *dvp,int namelen, char *name, int open_create_mode, u_int32_t create_attributes, int desired_acc_rights, struct ncp_open_info *nop, struct thread *td,struct ucred *cred) { struct ncp_conn *conn=NWFSTOCONN(nmp); struct ncp_rq *rqp; u_int16_t search_attribs = SA_ALL & (~SA_SUBDIR_FILES); u_int8_t volnum; u_int32_t dirent; int error; error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; volnum = nmp->n_volume; dirent = VTONW(dvp)->n_fid.f_id; if ((create_attributes & aDIR) != 0) { search_attribs |= SA_SUBDIR_FILES; } mb_put_uint8(&rqp->rq, 1);/* subfunction */ mb_put_uint8(&rqp->rq, nmp->name_space); mb_put_uint8(&rqp->rq, open_create_mode); mb_put_uint16le(&rqp->rq, search_attribs); mb_put_uint32le(&rqp->rq, IM_ALL); mb_put_uint32le(&rqp->rq, create_attributes); /* * The desired acc rights seem to be the inherited rights mask for * directories */ mb_put_uint16le(&rqp->rq, desired_acc_rights); ncp_rq_dbase_path(rqp, volnum, dirent, namelen, name, &nmp->m.nls); error = ncp_request(rqp); if (error) { if (error == NWE_FILE_NO_CREATE_PRIV) error = EACCES; return error; } md_get_uint32le(&rqp->rp, &nop->origfh); md_get_uint8(&rqp->rp, &nop->action); md_get_uint8(&rqp->rp, NULL); /* skip */ error = ncp_extract_file_info(nmp, rqp, &nop->fattr, 1); ncp_rq_done(rqp); ConvertToNWfromDWORD(nop->origfh, &nop->fh); return error; }
static NWCCODE ncp_log_physical_record64(NWCONN_HANDLE conn, u_int32_t fh, ncp_off64_t startOffset, u_int64_t length, unsigned int flags, unsigned int timeout) { NWCCODE err; ncp_init_request(conn); ncp_add_byte(conn, 67); ncp_add_dword_lh(conn, flags); ncp_add_dword_lh(conn, fh); ncp_add_qword_hl(conn, startOffset); ncp_add_qword_hl(conn, length); ncp_add_dword_hl(conn, timeout); err = ncp_request(conn, 87); ncp_unlock_conn(conn); return err; }
int ncp_get_bindery_object_name(NWCONN_HANDLE connid, u_int32_t object_id, struct ncp_bindery_object *target) { int error; DECLARE_RQ; ncp_init_request_s(conn, 54); ncp_add_dword_hl(conn, object_id); if ((error = ncp_request(connid, 23, conn)) != 0) return error; target->object_id = ncp_reply_dword_hl(conn, 0); target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6), 48); return 0; }
NWCCODE ncp_ns_search_entry_set(NWCONN_HANDLE conn, unsigned int search_attributes, const char* pattern, unsigned int datastream, u_int32_t rim, int* more, size_t *itemcount, struct ncp_search_seq* seq, void* buffer, size_t* size) { size_t slen; NWCCODE result; ncp_init_request(conn); ncp_add_byte(conn, 0x14); ncp_add_byte(conn, seq->name_space); ncp_add_byte(conn, datastream); ncp_add_word_lh(conn, search_attributes); ncp_add_dword_lh(conn, rim); ncp_add_word_lh(conn, *itemcount); ncp_add_mem(conn, &seq->s, 9); slen = pattern ? strlen(pattern) : 0; ncp_add_byte(conn, slen); if (slen) ncp_add_mem(conn, pattern, slen); result = ncp_request(conn, 0x57); if (result) { ncp_unlock_conn(conn); return result; } if (conn->ncp_reply_size < 9 + 1 + 2) { ncp_unlock_conn(conn); return NWE_INVALID_NCP_PACKET_LENGTH; } memcpy(&seq->s, ncp_reply_data(conn, 0), 9); *more = ncp_reply_byte(conn, 9); *itemcount = ncp_reply_word_lh(conn, 10); slen = conn->ncp_reply_size - 9 - 1 - 2; if (slen > *size) { slen = *size; result = NWE_BUFFER_OVERFLOW; } else *size = slen; memcpy(buffer, ncp_reply_data(conn, 12), slen); ncp_unlock_conn(conn); return result; }
int ncp_write(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred) { int error = 0, len, tsiz, backup; DECLARE_RQ; if (uiop->uio_iovcnt != 1) { printf("%s: can't handle iovcnt>1 !!!\n", __FUNCTION__); return EIO; } tsiz = uiop->uio_resid; while (tsiz > 0) { len = min(4096 - (uiop->uio_offset % 4096), tsiz); len = min(len, conn->buffer_size); if (len == 0) { printf("gotcha!\n"); } /* rq head */ NCP_RQ_HEAD(73,uiop->uio_procp,cred); ncp_rq_byte(rqp, 0); ncp_rq_mem(rqp, (caddr_t)file, 6); ncp_rq_dword(rqp, htonl(uiop->uio_offset)); ncp_rq_word_hl(rqp, len); nwfs_uiotombuf(uiop,&rqp->mrq,len,&rqp->bpos); checkbad(ncp_request(conn,rqp)); if (len == 0) break; NCP_RQ_EXIT; if (error) { backup = len; uiop->uio_iov->iov_base -= backup; uiop->uio_iov->iov_len += backup; uiop->uio_offset -= backup; uiop->uio_resid += backup; break; } tsiz -= len; } if (error) uiop->uio_resid = tsiz; switch (error) { case NWE_INSUFFICIENT_SPACE: error = ENOSPC; break; } return (error); }
static NWCCODE ncp_clear_release_physical_record64(NWCONN_HANDLE conn, u_int32_t fh, ncp_off64_t startOffset, u_int64_t length, int release) { NWCCODE err; ncp_init_request(conn); if (release) { ncp_add_byte(conn, 68); } else { ncp_add_byte(conn, 69); } ncp_add_dword_lh(conn, fh); ncp_add_qword_hl(conn, startOffset); ncp_add_qword_hl(conn, length); err = ncp_request(conn, 87); ncp_unlock_conn(conn); return err; }
int ncp_close_file(struct ncp_conn *conn, ncp_fh *fh,struct thread *td,struct ucred *cred) { struct ncp_rq *rqp; int error; error = ncp_rq_alloc(66, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 0); mb_put_mem(&rqp->rq, (caddr_t)fh, 6, MB_MSYSTEM); error = ncp_request(rqp); if (error) return error; ncp_rq_done(rqp); return error; }
int ncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd, struct ncp_bindery_object *objinfo) { u_long id = htonl(objinfo->object_id); u_char cryptkey[8]; u_char buf[128]; DECLARE_RQ; nw_keyhash((u_char *)&id, passwd, strlen(passwd), buf); nw_encrypt(key, buf, cryptkey); ncp_init_request_s(conn, 74); ncp_add_mem(conn, cryptkey, sizeof(cryptkey)); ncp_add_word_hl(conn, objinfo->object_type); ncp_add_pstring(conn, objinfo->object_name); return ncp_request(cH, 23, conn); }
int ncp_DeleteNSEntry(struct nwmount *nmp, u_int32_t dirent, int namelen,char *name,struct thread *td,struct ucred *cred) { struct ncp_rq *rqp; int error; struct ncp_conn *conn=NWFSTOCONN(nmp); error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 8); /* subfunction */ mb_put_uint8(&rqp->rq, nmp->name_space); mb_put_uint8(&rqp->rq, 0); /* reserved */ mb_put_uint16le(&rqp->rq, SA_ALL); /* search attribs: all */ ncp_rq_dbase_path(rqp, nmp->n_volume, dirent, namelen, name, &nmp->m.nls); error = ncp_request(rqp); if (!error) ncp_rq_done(rqp); return error; }
int ncp_read_property_value(NWCONN_HANDLE connid, int object_type, const char *object_name, int segment, const char *prop_name, struct nw_property *target) { int error; struct ncp_buf conn; ncp_init_request_s(&conn, 61); ncp_add_word_hl(&conn, object_type); ncp_add_pstring(&conn, object_name); ncp_add_byte(&conn, segment); ncp_add_pstring(&conn, prop_name); if ((error = ncp_request(connid,23,&conn)) != 0) { return error; } memcpy(&(target->value), ncp_reply_data(&conn, 0), 128); target->more_flag = ncp_reply_byte(&conn, 128); target->property_flag = ncp_reply_byte(&conn, 129); return 0; }
int ncp_get_bindery_object_id(NWCONN_HANDLE connid, u_int16_t object_type, const char *object_name, struct ncp_bindery_object *target) { int error; DECLARE_RQ; ncp_init_request_s(conn, 53); ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); if ((error = ncp_request(connid, 23, conn)) != 0) { return error; } if (conn->rpsize < 54) { return EACCES; } target->object_id = ncp_reply_dword_hl(conn, 0); target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6), 48); return 0; }
int ncp_read(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred) { int error = 0, len = 0, retlen=0, tsiz, burstio; DECLARE_RQ; tsiz = uiop->uio_resid; #ifdef NCPBURST burstio = (ncp_burst_enabled && tsiz > conn->buffer_size); #else burstio = 0; #endif while (tsiz > 0) { if (!burstio) { len = min(4096 - (uiop->uio_offset % 4096), tsiz); len = min(len, conn->buffer_size); NCP_RQ_HEAD(72,uiop->uio_procp,cred); ncp_rq_byte(rqp, 0); ncp_rq_mem(rqp, (caddr_t)file, 6); ncp_rq_dword(rqp, htonl(uiop->uio_offset)); ncp_rq_word(rqp, htons(len)); checkbad(ncp_request(conn,rqp)); retlen = ncp_rp_word_hl(rqp); if (uiop->uio_offset & 1) ncp_rp_byte(rqp); error = nwfs_mbuftouio(&rqp->mrp,uiop,retlen,&rqp->bpos); NCP_RQ_EXIT; } else { #ifdef NCPBURST error = ncp_burst_read(conn, file, tsiz, &len, &retlen, uiop, cred); #endif } if (error) break; tsiz -= retlen; if (retlen < len) break; } return (error); }
int ncp_scan_bindery_object(NWCONN_HANDLE connid, u_int32_t last_id, u_int16_t object_type, const char *search_string, struct ncp_bindery_object *target) { int error; DECLARE_RQ; ncp_init_request_s(conn, 55); ncp_add_dword_hl(conn, last_id); ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, search_string); error = ncp_request(connid, 23, conn); if (error) return error; target->object_id = ncp_reply_dword_hl(conn, 0); target->object_type = ncp_reply_word_hl(conn, 4); memcpy(target->object_name, ncp_reply_data(conn, 6),NCP_BINDERY_NAME_LEN); target->object_flags = ncp_reply_byte(conn, 54); target->object_security = ncp_reply_byte(conn, 55); target->object_has_prop = ncp_reply_byte(conn, 56); return 0; }
int ncp_get_bindery_object_id(struct ncp_conn *conn, u_int16_t object_type, char *object_name, struct ncp_bindery_object *target, struct proc *p,struct ucred *cred) { int error; DECLARE_RQ; NCP_RQ_HEAD_S(23,53,p,cred); ncp_rq_word_hl(rqp, object_type); ncp_rq_pstring(rqp, object_name); checkbad(ncp_request(conn,rqp)); if (rqp->rpsize < 54) { printf("ncp_rp_size %d < 54\n", rqp->rpsize); error = EINVAL; goto bad; } target->object_id = ncp_rp_dword_hl(rqp); target->object_type = ncp_rp_word_hl(rqp); ncp_rp_mem(rqp,(caddr_t)target->object_name, 48); NCP_RQ_EXIT; return error; }