NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor) { int i = 0; if (gss_maj == GSS_S_COMPLETE) { return NT_STATUS_OK; } if (gss_maj == GSS_S_CONTINUE_NEEDED) { return NT_STATUS_MORE_PROCESSING_REQUIRED; } if (gss_maj == GSS_S_FAILURE) { return map_nt_error_from_unix((int)minor); } /* Look through list */ while(gss_to_ntstatus_errormap[i].gss_err != 0) { if (gss_to_ntstatus_errormap[i].gss_err == gss_maj) { return gss_to_ntstatus_errormap[i].ntstatus; } i++; } /* Default return */ return NT_STATUS_ACCESS_DENIED; }
static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, const char *fname, DATA_BLOB *pblob) { connection_struct *conn = handle->conn; int ret; int saved_errno = 0; DEBUG(10,("store_acl_blob_pathname: storing blob " "length %u on file %s\n", (unsigned int)pblob->length, fname)); become_root(); ret = SMB_VFS_SETXATTR(conn, fname, XATTR_NTACL_NAME, pblob->data, pblob->length, 0); if (ret) { saved_errno = errno; } unbecome_root(); if (ret) { errno = saved_errno; DEBUG(5, ("store_acl_blob_pathname: setting attr failed " "for file %s with error %s\n", fname, strerror(errno) )); return map_nt_error_from_unix(errno); } return NT_STATUS_OK; }
static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, smbacl4_vfs_params *params, uint32_t security_info, TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, struct SMB4ACL_T *theacl) { int good_aces = 0; struct dom_sid sid_owner, sid_group; size_t sd_size = 0; struct security_ace *nt_ace_list = NULL; struct security_acl *psa = NULL; TALLOC_CTX *frame = talloc_stackframe(); bool ok; if (theacl==NULL) { TALLOC_FREE(frame); return NT_STATUS_ACCESS_DENIED; /* special because we * need to think through * the null case.*/ } uid_to_sid(&sid_owner, sbuf->st_ex_uid); gid_to_sid(&sid_group, sbuf->st_ex_gid); ok = smbacl4_nfs42win(frame, params, theacl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_ex_mode), &nt_ace_list, &good_aces); if (!ok) { DEBUG(8,("smbacl4_nfs42win failed\n")); TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } psa = make_sec_acl(frame, NT4_ACL_REVISION, good_aces, nt_ace_list); if (psa == NULL) { DEBUG(2,("make_sec_acl failed\n")); TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } DEBUG(10,("after make sec_acl\n")); *ppdesc = make_sec_desc( mem_ctx, SD_REVISION, smbacl4_get_controlflags(theacl), (security_info & SECINFO_OWNER) ? &sid_owner : NULL, (security_info & SECINFO_GROUP) ? &sid_group : NULL, NULL, psa, &sd_size); if (*ppdesc==NULL) { DEBUG(2,("make_sec_desc failed\n")); TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with " "sd_size %d\n", (int)ndr_size_security_descriptor(*ppdesc, 0))); TALLOC_FREE(frame); return NT_STATUS_OK; }
/* setup the inotify handle - called the first time a watch is added on this context */ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) { struct inotify_private *in; if (!lp_parm_bool(-1, "notify", "inotify", True)) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } in = talloc(ctx, struct inotify_private); NT_STATUS_HAVE_NO_MEMORY(in); in->fd = inotify_init(); if (in->fd == -1) { DEBUG(0,("Failed to init inotify - %s\n", strerror(errno))); talloc_free(in); return map_nt_error_from_unix(errno); } in->ctx = ctx; in->watches = NULL; ctx->private_data = in; talloc_set_destructor(in, inotify_destructor); /* add a event waiting for the inotify fd to be readable */ tevent_add_fd(ctx->ev, in, in->fd, TEVENT_FD_READ, inotify_handler, in); return NT_STATUS_OK; }
static NTSTATUS store_memory_creds(struct WINBINDD_MEMORY_CREDS *memcredp, const char *pass) { #if !defined(HAVE_MLOCK) return NT_STATUS_OK; #else /* new_entry->nt_hash is the base pointer for the block of memory pointed into by new_entry->lm_hash and new_entry->pass (if we're storing plaintext). */ memcredp->len = NT_HASH_LEN + LM_HASH_LEN; if (pass) { memcredp->len += strlen(pass)+1; } #if defined(LINUX) /* aligning the memory on on x86_64 and compiling with gcc 4.1 using -O2 causes a segv in the next memset() --jerry */ memcredp->nt_hash = SMB_MALLOC_ARRAY(unsigned char, memcredp->len); #else /* On non-linux platforms, mlock()'d memory must be aligned */ memcredp->nt_hash = SMB_MEMALIGN_ARRAY(unsigned char, getpagesize(), memcredp->len); #endif if (!memcredp->nt_hash) { return NT_STATUS_NO_MEMORY; } memset(memcredp->nt_hash, 0x0, memcredp->len); memcredp->lm_hash = memcredp->nt_hash + NT_HASH_LEN; #ifdef DEBUG_PASSWORD DEBUG(10,("mlocking memory: %p\n", memcredp->nt_hash)); #endif if ((mlock(memcredp->nt_hash, memcredp->len)) == -1) { DEBUG(0,("failed to mlock memory: %s (%d)\n", strerror(errno), errno)); SAFE_FREE(memcredp->nt_hash); return map_nt_error_from_unix(errno); } #ifdef DEBUG_PASSWORD DEBUG(10,("mlocked memory: %p\n", memcredp->nt_hash)); #endif if (pass) { /* Create and store the password hashes. */ E_md4hash(pass, memcredp->nt_hash); E_deshash(pass, memcredp->lm_hash); memcredp->pass = (char *)memcredp->lm_hash + LM_HASH_LEN; memcpy(memcredp->pass, pass, memcredp->len - NT_HASH_LEN - LM_HASH_LEN); } return NT_STATUS_OK; #endif }
WERROR regdb_open( void ) { WERROR result = WERR_OK; if ( regdb ) { DEBUG(10, ("regdb_open: incrementing refcount (%d->%d)\n", regdb_refcount, regdb_refcount+1)); regdb_refcount++; return WERR_OK; } become_root(); regdb = db_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600); if ( !regdb ) { result = ntstatus_to_werror( map_nt_error_from_unix( errno ) ); DEBUG(0,("regdb_open: Failed to open %s! (%s)\n", state_path("registry.tdb"), strerror(errno) )); } unbecome_root(); regdb_refcount = 1; DEBUG(10, ("regdb_open: registry db opened. refcount reset (%d)\n", regdb_refcount)); return result; }
static NTSTATUS ipv6_init(struct socket_context *sock) { int type; switch (sock->type) { case SOCKET_TYPE_STREAM: type = SOCK_STREAM; break; case SOCKET_TYPE_DGRAM: type = SOCK_DGRAM; break; default: return NT_STATUS_INVALID_PARAMETER; } sock->fd = socket(PF_INET6, type, 0); if (sock->fd == -1) { return map_nt_error_from_unix(errno); } sock->backend_name = "ipv6"; sock->family = AF_INET6; return NT_STATUS_OK; }
NTSTATUS set_create_timespec_ea(connection_struct *conn, const struct smb_filename *psmb_fname, struct timespec create_time) { struct smb_filename *smb_fname; uint32_t dosmode; int ret; if (!lp_store_dos_attributes(SNUM(conn))) { return NT_STATUS_OK; } smb_fname = synthetic_smb_fname(talloc_tos(), psmb_fname->base_name, NULL, &psmb_fname->st); if (smb_fname == NULL) { return NT_STATUS_NO_MEMORY; } dosmode = dos_mode(conn, smb_fname); smb_fname->st.st_ex_btime = create_time; ret = file_set_dosmode(conn, smb_fname, dosmode, NULL, false); if (ret == -1) { map_nt_error_from_unix(errno); } DEBUG(10,("set_create_timespec_ea: wrote create time EA for file %s\n", smb_fname_str_dbg(smb_fname))); return NT_STATUS_OK; }
/* write to a file */ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *wr) { struct svfs_private *p = ntvfs->private_data; struct svfs_file *f; ssize_t ret; if (wr->generic.level != RAW_WRITE_WRITEX) { return ntvfs_map_write(ntvfs, req, wr); } CHECK_READ_ONLY(req); f = find_fd(p, wr->writex.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } ret = pwrite(f->fd, wr->writex.in.data, wr->writex.in.count, wr->writex.in.offset); if (ret == -1) { return map_nt_error_from_unix(errno); } wr->writex.out.nwritten = ret; wr->writex.out.remaining = 0; /* should fill this in? */ return NT_STATUS_OK; }
static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, files_struct *fsp, DATA_BLOB *pblob) { int ret; int saved_errno = 0; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", (unsigned int)pblob->length, fsp_str_dbg(fsp))); become_root(); if (fsp->fh->fd != -1) { ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME, pblob->data, pblob->length, 0); } else { ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name, XATTR_NTACL_NAME, pblob->data, pblob->length, 0); } if (ret) { saved_errno = errno; } unbecome_root(); if (ret) { errno = saved_errno; DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s" "with error %s\n", fsp_str_dbg(fsp), strerror(errno) )); return map_nt_error_from_unix(errno); } return NT_STATUS_OK; }
static WERROR backup_registry_key(struct registry_key_handle *krecord, const char *fname) { REGF_FILE *regfile; WERROR result; /* open the registry file....fail if the file already exists */ regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL), (S_IRUSR|S_IWUSR)); if (regfile == NULL) { DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", fname, strerror(errno) )); return ntstatus_to_werror(map_nt_error_from_unix(errno)); } /* write the registry tree to the file */ result = reg_write_tree(regfile, krecord->name, NULL); /* cleanup */ regfio_close(regfile); return result; }
WERROR regdb_open( void ) { WERROR result = WERR_OK; if ( tdb_reg ) { DEBUG(10,("regdb_open: incrementing refcount (%d)\n", tdb_refcount)); tdb_refcount++; return WERR_OK; } become_root(); tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600); if ( !tdb_reg ) { result = ntstatus_to_werror( map_nt_error_from_unix( errno ) ); DEBUG(0,("regdb_open: Failed to open %s! (%s)\n", lock_path("registry.tdb"), strerror(errno) )); } unbecome_root(); tdb_refcount = 1; DEBUG(10,("regdb_open: refcount reset (%d)\n", tdb_refcount)); return result; }
/* do a rough conversion between ads error codes and NT status codes we'll need to fill this in more */ NTSTATUS ads_ntstatus(ADS_STATUS status) { switch (status.error_type) { case ENUM_ADS_ERROR_NT: return status.err.nt_status; case ENUM_ADS_ERROR_SYSTEM: return map_nt_error_from_unix(status.err.rc); #ifdef HAVE_LDAP case ENUM_ADS_ERROR_LDAP: if (status.err.rc == LDAP_SUCCESS) { return NT_STATUS_OK; } return NT_STATUS_LDAP(status.err.rc); #endif #ifdef HAVE_KRB5 case ENUM_ADS_ERROR_KRB5: return krb5_to_nt_status(status.err.rc); #endif default: break; } if (ADS_ERR_OK(status)) { return NT_STATUS_OK; } return NT_STATUS_UNSUCCESSFUL; }
static WERROR restore_registry_key(struct registry_key_handle *krecord, const char *fname) { REGF_FILE *regfile; REGF_NK_REC *rootkey; WERROR result; /* open the registry file....fail if the file already exists */ regfile = regfio_open(fname, (O_RDONLY), 0); if (regfile == NULL) { DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n", fname, strerror(errno))); return ntstatus_to_werror(map_nt_error_from_unix(errno)); } /* get the rootkey from the regf file and then load the tree via recursive calls */ if (!(rootkey = regfio_rootkey(regfile))) { regfio_close(regfile); return WERR_REG_FILE_INVALID; } result = reg_load_tree(regfile, krecord->name, rootkey); /* cleanup */ regfio_close(regfile); return result; }
static NTSTATUS ipv6_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, const struct socket_address *dest_addr) { ssize_t len; if (dest_addr->sockaddr) { len = sendto(sock->fd, blob->data, blob->length, 0, dest_addr->sockaddr, dest_addr->sockaddrlen); } else { struct sockaddr_in6 srv_addr; struct in6_addr addr; ZERO_STRUCT(srv_addr); addr = interpret_addr6(dest_addr->addr); if (addr.s6_addr == 0) { return NT_STATUS_HOST_UNREACHABLE; } srv_addr.sin6_addr = addr; srv_addr.sin6_port = htons(dest_addr->port); srv_addr.sin6_family = PF_INET6; *sendlen = 0; len = sendto(sock->fd, blob->data, blob->length, 0, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); } if (len == -1) { return map_nt_error_from_unix(errno); } *sendlen = len; return NT_STATUS_OK; }
/* close a file */ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_close *io) { struct svfs_private *p = ntvfs->private_data; struct svfs_file *f; if (io->generic.level != RAW_CLOSE_CLOSE) { /* we need a mapping function */ return NT_STATUS_INVALID_LEVEL; } f = find_fd(p, io->close.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } if (close(f->fd) == -1) { return map_nt_error_from_unix(errno); } DLIST_REMOVE(p->open_files, f); talloc_free(f->name); talloc_free(f); return NT_STATUS_OK; }
/* return filesystem attribute info */ static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsattr *fs) { struct stat st; struct svfs_private *p = ntvfs->private_data; if (fs->generic.level != RAW_FSATTR_GENERIC) { return ntvfs_map_fsattr(ntvfs, req, fs); } if (stat(p->connectpath, &st) == -1) { return map_nt_error_from_unix(errno); } unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); fs->generic.out.fs_attr = FILE_CASE_PRESERVED_NAMES | FILE_CASE_SENSITIVE_SEARCH | FILE_PERSISTENT_ACLS; fs->generic.out.max_file_component_length = 255; fs->generic.out.serial_number = 1; fs->generic.out.fs_type = talloc_strdup(req, "NTFS"); fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(req->tcon->service)); return NT_STATUS_OK; }
/* read from a file */ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_read *rd) { struct svfs_private *p = ntvfs->private_data; struct svfs_file *f; ssize_t ret; if (rd->generic.level != RAW_READ_READX) { return NT_STATUS_NOT_SUPPORTED; } f = find_fd(p, rd->readx.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } ret = pread(f->fd, rd->readx.out.data, rd->readx.in.maxcnt, rd->readx.in.offset); if (ret == -1) { return map_nt_error_from_unix(errno); } rd->readx.out.nread = ret; rd->readx.out.remaining = 0; /* should fill this in? */ rd->readx.out.compaction_mode = 0; return NT_STATUS_OK; }
/* Fetch the NFSv4 ACL from the xattr, and convert into Samba's internal NFSv4 format */ static NTSTATUS nfs4_get_nfs4_acl(vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, const char *path, struct SMB4ACL_T **ppacl) { NTSTATUS status; DATA_BLOB blob = data_blob_null; ssize_t length; TALLOC_CTX *frame = talloc_stackframe(); do { blob.length += 1000; blob.data = talloc_realloc(frame, blob.data, uint8_t, blob.length); if (!blob.data) { TALLOC_FREE(frame); errno = ENOMEM; return NT_STATUS_NO_MEMORY; } length = SMB_VFS_NEXT_GETXATTR(handle, path, NFS4ACL_XATTR_NAME, blob.data, blob.length); blob.length = length; } while (length == -1 && errno == ERANGE); if (length == -1) { TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } status = nfs4_get_nfs4_acl_common(mem_ctx, &blob, ppacl); TALLOC_FREE(frame); return status; }
static NTSTATUS gpo_copy_dir(const char *unix_path) { if ((mkdir(unix_path, 0644)) < 0 && errno != EEXIST) { return map_nt_error_from_unix(errno); } return NT_STATUS_OK; }
static void open_socket_out_connected(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct open_socket_out_state *state = tevent_req_data(req, struct open_socket_out_state); int ret; int sys_errno; ret = async_connect_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == 0) { tevent_req_done(req); return; } if ( #ifdef ETIMEDOUT (sys_errno == ETIMEDOUT) || #endif (sys_errno == EINPROGRESS) || (sys_errno == EALREADY) || (sys_errno == EAGAIN)) { /* * retry */ if (state->wait_usec < 250000) { state->wait_usec *= 1.5; } subreq = async_connect_send(state, state->ev, state->fd, (struct sockaddr *)&state->ss, state->salen); if (tevent_req_nomem(subreq, req)) { return; } if (!tevent_req_set_endtime( subreq, state->ev, timeval_current_ofs_usec(state->wait_usec))) { tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } tevent_req_set_callback(subreq, open_socket_out_connected, req); return; } #ifdef EISCONN if (sys_errno == EISCONN) { tevent_req_done(req); return; } #endif /* real error */ tevent_req_nterror(req, map_nt_error_from_unix(sys_errno)); }
static NTSTATUS ipv6_listen(struct socket_context *sock, const struct socket_address *my_address, int queue_size, uint32_t flags) { struct sockaddr_in6 my_addr; struct in6_addr ip_addr; int ret; socket_set_option(sock, "SO_REUSEADDR=1", NULL); if (my_address->sockaddr) { ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); } else { ip_addr = interpret_addr6(my_address->addr); ZERO_STRUCT(my_addr); my_addr.sin6_addr = ip_addr; my_addr.sin6_port = htons(my_address->port); my_addr.sin6_family = PF_INET6; ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); } if (ret == -1) { return map_nt_error_from_unix(errno); } if (sock->type == SOCKET_TYPE_STREAM) { ret = listen(sock->fd, queue_size); if (ret == -1) { return map_nt_error_from_unix(errno); } } if (!(flags & SOCKET_FLAG_BLOCK)) { ret = set_blocking(sock->fd, false); if (ret == -1) { return map_nt_error_from_unix(errno); } } sock->state= SOCKET_STATE_SERVER_LISTEN; return NT_STATUS_OK; }
static NTSTATUS ip_pending(struct socket_context *sock, size_t *npending) { int value = 0; if (ioctl(sock->fd, FIONREAD, &value) == 0) { *npending = value; return NT_STATUS_OK; } return map_nt_error_from_unix(errno); }
static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, struct files_struct *fsp, const struct smb_filename *smb_fname, TALLOC_CTX *mem_ctx, unsigned int *pnum_streams, struct stream_struct **pstreams) { SMB_STRUCT_STAT sbuf; int ret; NTSTATUS status; struct streaminfo_state state; ret = vfs_stat_smb_basename(handle->conn, smb_fname, &sbuf); if (ret == -1) { return map_nt_error_from_unix(errno); } state.streams = *pstreams; state.num_streams = *pnum_streams; state.mem_ctx = mem_ctx; state.handle = handle; state.status = NT_STATUS_OK; if (S_ISLNK(sbuf.st_ex_mode)) { /* * Currently we do't have SMB_VFS_LLISTXATTR * inside the VFS which means there's no way * to cope with a symlink when lp_posix_pathnames(). * returns true. For now ignore links. * FIXME - by adding SMB_VFS_LLISTXATTR. JRA. */ status = NT_STATUS_OK; } else { status = walk_xattr_streams(handle, fsp, smb_fname, collect_one_stream, &state); } if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(state.streams); return status; } if (!NT_STATUS_IS_OK(state.status)) { TALLOC_FREE(state.streams); return state.status; } *pnum_streams = state.num_streams; *pstreams = state.streams; return SMB_VFS_NEXT_STREAMINFO(handle, fsp, smb_fname, mem_ctx, pnum_streams, pstreams); }
static NTSTATUS ipv6_recvfrom(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, TALLOC_CTX *addr_ctx, struct socket_address **_src) { ssize_t gotlen; struct sockaddr_in6 *from_addr; socklen_t from_len = sizeof(*from_addr); struct socket_address *src; char addrstring[INET6_ADDRSTRLEN]; src = talloc(addr_ctx, struct socket_address); if (!src) { return NT_STATUS_NO_MEMORY; } src->family = sock->backend_name; from_addr = talloc(src, struct sockaddr_in6); if (!from_addr) { talloc_free(src); return NT_STATUS_NO_MEMORY; } src->sockaddr = (struct sockaddr *)from_addr; *nread = 0; gotlen = recvfrom(sock->fd, buf, wantlen, 0, src->sockaddr, &from_len); if (gotlen == 0) { talloc_free(src); return NT_STATUS_END_OF_FILE; } else if (gotlen == -1) { talloc_free(src); return map_nt_error_from_unix(errno); } src->sockaddrlen = from_len; if (inet_ntop(AF_INET6, &from_addr->sin6_addr, addrstring, sizeof(addrstring)) == NULL) { DEBUG(0, ("Unable to convert address to string: %s\n", strerror(errno))); talloc_free(src); return NT_STATUS_INTERNAL_ERROR; } src->addr = talloc_strdup(src, addrstring); if (src->addr == NULL) { talloc_free(src); return NT_STATUS_NO_MEMORY; } src->port = ntohs(from_addr->sin6_port); *nread = gotlen; *_src = src; return NT_STATUS_OK; }
NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx, struct cli_state *cli, const char *nt_path, const char *unix_path) { NTSTATUS result; int fnum; int fd = 0; char *data = NULL; static int io_bufsize = 64512; int read_size = io_bufsize; off_t start = 0; off_t nread = 0; if ((fnum = cli_open(cli, nt_path, O_RDONLY, DENY_NONE)) == -1) { result = NT_STATUS_NO_SUCH_FILE; goto out; } if ((fd = sys_open(unix_path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { result = map_nt_error_from_unix(errno); goto out; } if ((data = (char *)SMB_MALLOC(read_size)) == NULL) { result = NT_STATUS_NO_MEMORY; goto out; } while (1) { int n = cli_read(cli, fnum, data, nread + start, read_size); if (n <= 0) break; if (write(fd, data, n) != n) { break; } nread += n; } result = NT_STATUS_OK; out: SAFE_FREE(data); if (fnum) { cli_close(cli, fnum); } if (fd) { close(fd); } return result; }
static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, vfs_handle_struct *handle, files_struct *fsp, const struct smb_filename *smb_fname, DATA_BLOB *pblob) { uint8_t id_buf[16]; TDB_DATA data; struct file_id id; struct db_context *db = acl_db; NTSTATUS status = NT_STATUS_OK; SMB_STRUCT_STAT sbuf; ZERO_STRUCT(sbuf); if (fsp) { status = vfs_stat_fsp(fsp); sbuf = fsp->fsp_name->st; } else { int ret = vfs_stat_smb_basename(handle->conn, smb_fname, &sbuf); if (ret == -1) { status = map_nt_error_from_unix(errno); } } if (!NT_STATUS_IS_OK(status)) { return status; } id = vfs_file_id_from_sbuf(handle->conn, &sbuf); /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, &id); status = dbwrap_fetch(db, ctx, make_tdb_data(id_buf, sizeof(id_buf)), &data); if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } pblob->data = data.dptr; pblob->length = data.dsize; DEBUG(10,("get_acl_blob: returned %u bytes from file %s\n", (unsigned int)data.dsize, smb_fname->base_name )); if (pblob->length == 0 || pblob->data == NULL) { return NT_STATUS_NOT_FOUND; } return NT_STATUS_OK; }
NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint8_t trans_cmd, const char *pipe_name, uint16_t fid, uint16_t function, int flags, uint16_t *setup, uint8_t num_setup, uint8_t max_setup, uint8_t *param, uint32_t num_param, uint32_t max_param, uint8_t *data, uint32_t num_data, uint32_t max_data, uint16_t **rsetup, uint8_t *num_rsetup, uint8_t **rparam, uint32_t *num_rparam, uint8_t **rdata, uint32_t *num_rdata) { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; struct tevent_req *req; NTSTATUS status = NT_STATUS_OK; if (cli_has_async_calls(cli)) { /* * Can't use sync call while an async call is in flight */ status = NT_STATUS_INVALID_PARAMETER; goto fail; } ev = event_context_init(frame); if (ev == NULL) { status = NT_STATUS_NO_MEMORY; goto fail; } req = cli_trans_send(frame, ev, cli, trans_cmd, pipe_name, fid, function, flags, setup, num_setup, max_setup, param, num_param, max_param, data, num_data, max_data); if (req == NULL) { status = NT_STATUS_NO_MEMORY; goto fail; } if (!tevent_req_poll(req, ev)) { status = map_nt_error_from_unix(errno); goto fail; } status = cli_trans_recv(req, mem_ctx, rsetup, num_rsetup, rparam, num_rparam, rdata, num_rdata); fail: TALLOC_FREE(frame); if (!NT_STATUS_IS_OK(status)) { cli_set_error(cli, status); } return status; }
NTSTATUS check_veto_path(connection_struct *conn, const char *name) { if (IS_VETO_PATH(conn, name)) { /* Is it not dot or dot dot. */ if (!(ISDOT(name) || ISDOTDOT(name))) { DEBUG(5,("check_veto_path: file path name %s vetoed\n", name)); return map_nt_error_from_unix(ENOENT); } } return NT_STATUS_OK; }
static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, vfs_handle_struct *handle, files_struct *fsp, const struct smb_filename *smb_fname, DATA_BLOB *pblob) { size_t size = 1024; uint8_t *val = NULL; uint8_t *tmp; ssize_t sizeret; int saved_errno = 0; ZERO_STRUCTP(pblob); again: tmp = talloc_realloc(ctx, val, uint8_t, size); if (tmp == NULL) { TALLOC_FREE(val); return NT_STATUS_NO_MEMORY; } val = tmp; become_root(); if (fsp && fsp->fh->fd != -1) { sizeret = SMB_VFS_FGETXATTR(fsp, XATTR_NTACL_NAME, val, size); } else { sizeret = SMB_VFS_GETXATTR(handle->conn, smb_fname->base_name, XATTR_NTACL_NAME, val, size); } if (sizeret == -1) { saved_errno = errno; } unbecome_root(); /* Max ACL size is 65536 bytes. */ if (sizeret == -1) { errno = saved_errno; if ((errno == ERANGE) && (size != 65536)) { /* Too small, try again. */ size = 65536; goto again; } /* Real error - exit here. */ TALLOC_FREE(val); return map_nt_error_from_unix(errno); } pblob->data = val; pblob->length = sizeret; return NT_STATUS_OK; }