/* * Create a standard "Unix" pid file. */ void create_pid_file(char *dir, const char *progname, int port) { #if !defined(HAVE_WIN32) int pidfd, len; int oldpid; char pidbuf[20]; POOLMEM *fname = get_pool_memory(PM_FNAME); struct stat statp; Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port); if (stat(fname, &statp) == 0) { /* File exists, see what we have */ *pidbuf = 0; if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 || read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 || sscanf(pidbuf, "%d", &oldpid) != 1) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, be.bstrerror()); } /* Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and * since they use a deterministic algorithm for assigning PIDs, we can have * pid conflicts with the old PID file after a reboot. * The intent the following code is to check if the oldpid read from the pid * file is the same as the currently executing process's pid, * and if oldpid == getpid(), skip the attempt to * kill(oldpid,0), since the attempt is guaranteed to succeed, * but the success won't actually mean that there is an * another BAREOS process already running. * For more details see bug #797. */ if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) { Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"), progname, oldpid, fname); } /* He is not alive, so take over file ownership */ unlink(fname); /* remove stale pid file */ } /* Create new pid file */ if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) { len = sprintf(pidbuf, "%d\n", (int)getpid()); write(pidfd, pidbuf, len); close(pidfd); del_pid_file_ok = TRUE; /* we created it so we can delete it */ } else { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, be.bstrerror()); } free_pool_memory(fname); #endif }
void b_UnlockRes(const char *file, int line) { int errstat; if ((errstat=rwl_writeunlock(&res_lock)) != 0) { Emsg3(M_ABORT, 0, _("rwl_writeunlock failure at %s:%d:. ERR=%s\n"), file, line, strerror(errstat)); } res_locked--; #ifdef TRACE_RES Pmsg4(000, "UnLockRes locked=%d wactive=%d at %s:%d\n", res_locked, res_lock.w_active, file, line); #endif }
void b_LockRes(const char *file, int line) { int errstat; #ifdef TRACE_RES Pmsg4(000, "LockRes locked=%d w_active=%d at %s:%d\n", res_locked, res_lock.w_active, file, line); if (res_locked) { Pmsg2(000, "LockRes writerid=%d myid=%d\n", res_lock.writer_id, pthread_self()); } #endif if ((errstat=rwl_writelock(&res_lock)) != 0) { Emsg3(M_ABORT, 0, _("rwl_writelock failure at %s:%d: ERR=%s\n"), file, line, strerror(errstat)); } res_locked++; }
/* * Become Threaded Network Server * * This function is able to handle multiple server ips in * ipv4 and ipv6 style. The Addresse are give in a comma * seperated string in bind_addr * * At the moment it is impossible to bind to different ports. */ void bnet_thread_server(dlist *addr_list, int max_clients, alist *sockfds, workq_t *client_wq, void *handle_client_request(void *bsock)) { int newsockfd, status; socklen_t clilen; struct sockaddr cli_addr; /* client's address */ int tlog, tmax; int turnon = 1; #ifdef HAVE_LIBWRAP struct request_info request; #endif IPADDR *ipaddr, *next; s_sockfd *fd_ptr = NULL; char buf[128]; #ifdef HAVE_POLL nfds_t nfds; struct pollfd *pfds; #endif char allbuf[256 * 10]; /* * Remove any duplicate addresses. */ for (ipaddr = (IPADDR *)addr_list->first(); ipaddr; ipaddr = (IPADDR *)addr_list->next(ipaddr)) { for (next = (IPADDR *)addr_list->next(ipaddr); next; next = (IPADDR *)addr_list->next(next)) { if (ipaddr->get_sockaddr_len() == next->get_sockaddr_len() && memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(), ipaddr->get_sockaddr_len()) == 0) { addr_list->remove(next); } } } Dmsg1(100, "Addresses %s\n", build_addresses_str(addr_list, allbuf, sizeof(allbuf))); #ifdef HAVE_POLL nfds = 0; #endif foreach_dlist(ipaddr, addr_list) { /* * Allocate on stack from -- no need to free */ fd_ptr = (s_sockfd *)alloca(sizeof(s_sockfd)); fd_ptr->port = ipaddr->get_port_net_order(); /* * Open a TCP socket */ for (tlog= 60; (fd_ptr->fd=socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0; tlog -= 10) { if (tlog <= 0) { berrno be; char curbuf[256]; Emsg3(M_ABORT, 0, _("Cannot open stream socket. ERR=%s. Current %s All %s\n"), be.bstrerror(), ipaddr->build_address_str(curbuf, sizeof(curbuf)), build_addresses_str(addr_list, allbuf, sizeof(allbuf))); } bmicrosleep(10, 0); } /* * Reuse old sockets */ if (setsockopt(fd_ptr->fd, SOL_SOCKET, SO_REUSEADDR, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { berrno be; Emsg1(M_WARNING, 0, _("Cannot set SO_REUSEADDR on socket: %s\n"), be.bstrerror()); } tmax = 30 * (60 / 5); /* wait 30 minutes max */ for (tlog = 0; bind(fd_ptr->fd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0; tlog -= 5) { berrno be; if (tlog <= 0) { tlog = 2 * 60; /* Complain every 2 minutes */ Emsg2(M_WARNING, 0, _("Cannot bind port %d: ERR=%s: Retrying ...\n"), ntohs(fd_ptr->port), be.bstrerror()); } bmicrosleep(5, 0); if (--tmax <= 0) { Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), ntohs(fd_ptr->port), be.bstrerror()); } } listen(fd_ptr->fd, 50); /* tell system we are ready */ sockfds->append(fd_ptr); #ifdef HAVE_POLL nfds++; #endif }
/* * Called here for each record from read_records() */ static bool record_cb(DCR *dcr, DEV_RECORD *rec) { int status; JCR *jcr = dcr->jcr; if (rec->FileIndex < 0) { return true; /* we don't want labels */ } /* File Attributes stream */ switch (rec->maskedStream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: /* If extracting, it was from previous stream, so * close the output file. */ if (extract) { if (!is_bopen(&bfd)) { Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n")); } set_attributes(jcr, attr, &bfd); extract = false; } if (!unpack_attributes_record(jcr, rec->Stream, rec->data, rec->data_len, attr)) { Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); } if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) { attr->data_stream = decode_stat(attr->attr, &attr->statp, sizeof(attr->statp), &attr->LinkFI); if (!is_restore_stream_supported(attr->data_stream)) { if (!non_support_data++) { Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"), stream_to_ascii(attr->data_stream)); } extract = false; return true; } build_attr_output_fnames(jcr, attr); if (attr->type == FT_DELETED) { /* TODO: choose the right fname/ofname */ Jmsg(jcr, M_INFO, 0, _("%s was deleted.\n"), attr->fname); extract = false; return true; } extract = false; status = create_file(jcr, attr, &bfd, REPLACE_ALWAYS); switch (status) { case CF_ERROR: case CF_SKIP: break; case CF_EXTRACT: extract = true; print_ls_output(jcr, attr); num_files++; fileAddr = 0; break; case CF_CREATED: set_attributes(jcr, attr, &bfd); print_ls_output(jcr, attr); num_files++; fileAddr = 0; break; } } break; case STREAM_RESTORE_OBJECT: /* nothing to do */ break; /* Data stream and extracting */ case STREAM_FILE_DATA: case STREAM_SPARSE_DATA: case STREAM_WIN32_DATA: if (extract) { if (rec->maskedStream == STREAM_SPARSE_DATA) { ser_declare; uint64_t faddr; wbuf = rec->data + OFFSET_FADDR_SIZE; wsize = rec->data_len - OFFSET_FADDR_SIZE; ser_begin(rec->data, OFFSET_FADDR_SIZE); unser_uint64(faddr); if (fileAddr != faddr) { fileAddr = faddr; if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"), attr->ofname, be.bstrerror()); } } } else { wbuf = rec->data; wsize = rec->data_len; } total += wsize; Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total); store_data(&bfd, wbuf, wsize); fileAddr += wsize; } break; /* GZIP data stream */ case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_WIN32_GZIP_DATA: #ifdef HAVE_LIBZ if (extract) { uLong compress_len = compress_buf_size; int status = Z_BUF_ERROR; if (rec->maskedStream == STREAM_SPARSE_GZIP_DATA) { ser_declare; uint64_t faddr; char ec1[50]; wbuf = rec->data + OFFSET_FADDR_SIZE; wsize = rec->data_len - OFFSET_FADDR_SIZE; ser_begin(rec->data, OFFSET_FADDR_SIZE); unser_uint64(faddr); if (fileAddr != faddr) { fileAddr = faddr; if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) { berrno be; Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), edit_uint64(fileAddr, ec1), attr->ofname, be.bstrerror()); extract = false; return true; } } } else { wbuf = rec->data; wsize = rec->data_len; } while (compress_len < 10000000 && (status = uncompress((Byte *)compress_buf, &compress_len, (const Byte *)wbuf, (uLong)wsize)) == Z_BUF_ERROR) { /* The buffer size is too small, try with a bigger one */ compress_len = 2 * compress_len; compress_buf = check_pool_memory_size(compress_buf, compress_len); } if (status != Z_OK) { Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), status); extract = false; return true; } Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total); store_data(&bfd, compress_buf, compress_len); total += compress_len; fileAddr += compress_len; Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len, compress_len); } #else if (extract) { Emsg0(M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n")); extract = false; return true; } #endif break; /* Compressed data stream */ case STREAM_COMPRESSED_DATA: case STREAM_SPARSE_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: if (extract) { uint32_t comp_magic, comp_len; uint16_t comp_level, comp_version; #ifdef HAVE_LZO lzo_uint compress_len; const unsigned char *cbuf; int r, real_compress_len; #endif if (rec->maskedStream == STREAM_SPARSE_COMPRESSED_DATA) { ser_declare; uint64_t faddr; char ec1[50]; wbuf = rec->data + OFFSET_FADDR_SIZE; wsize = rec->data_len - OFFSET_FADDR_SIZE; ser_begin(rec->data, OFFSET_FADDR_SIZE); unser_uint64(faddr); if (fileAddr != faddr) { fileAddr = faddr; if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) { berrno be; Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), edit_uint64(fileAddr, ec1), attr->ofname, be.bstrerror()); extract = false; return true; } } } else { wbuf = rec->data; wsize = rec->data_len; } /* read compress header */ unser_declare; unser_begin(wbuf, sizeof(comp_stream_header)); unser_uint32(comp_magic); unser_uint32(comp_len); unser_uint16(comp_level); unser_uint16(comp_version); Dmsg4(200, "Compressed data stream found: magic=0x%x, len=%d, level=%d, ver=0x%x\n", comp_magic, comp_len, comp_level, comp_version); /* version check */ if (comp_version != COMP_HEAD_VERSION) { Emsg1(M_ERROR, 0, _("Compressed header version error. version=0x%x\n"), comp_version); return false; } /* size check */ if (comp_len + sizeof(comp_stream_header) != wsize) { Emsg2(M_ERROR, 0, _("Compressed header size error. comp_len=%d, msglen=%d\n"), comp_len, wsize); return false; } switch(comp_magic) { #ifdef HAVE_LZO case COMPRESS_LZO1X: compress_len = compress_buf_size; cbuf = (const unsigned char*) wbuf + sizeof(comp_stream_header); real_compress_len = wsize - sizeof(comp_stream_header); Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, wsize); while ((r=lzo1x_decompress_safe(cbuf, real_compress_len, (unsigned char *)compress_buf, &compress_len, NULL)) == LZO_E_OUTPUT_OVERRUN) { /* The buffer size is too small, try with a bigger one */ compress_len = 2 * compress_len; compress_buf = check_pool_memory_size(compress_buf, compress_len); } if (r != LZO_E_OK) { Emsg1(M_ERROR, 0, _("LZO uncompression error. ERR=%d\n"), r); extract = false; return true; } Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total); store_data(&bfd, compress_buf, compress_len); total += compress_len; fileAddr += compress_len; Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len, compress_len); break; #endif default: Emsg1(M_ERROR, 0, _("Compression algorithm 0x%x found, but not supported!\n"), comp_magic); extract = false; return true; } } break; case STREAM_MD5_DIGEST: case STREAM_SHA1_DIGEST: case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: break; case STREAM_SIGNED_DIGEST: case STREAM_ENCRYPTED_SESSION_DATA: // TODO landonf: Investigate crypto support in the storage daemon break; case STREAM_PROGRAM_NAMES: case STREAM_PROGRAM_DATA: if (!prog_name_msg) { Pmsg0(000, _("Got Program Name or Data Stream. Ignored.\n")); prog_name_msg++; } break; case STREAM_UNIX_ACCESS_ACL: /* Deprecated Standard ACL attributes on UNIX */ case STREAM_UNIX_DEFAULT_ACL: /* Deprecated Default ACL attributes on UNIX */ case STREAM_ACL_AIX_TEXT: case STREAM_ACL_DARWIN_ACCESS_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: case STREAM_ACL_HPUX_ACL_ENTRY: case STREAM_ACL_IRIX_DEFAULT_ACL: case STREAM_ACL_IRIX_ACCESS_ACL: case STREAM_ACL_LINUX_DEFAULT_ACL: case STREAM_ACL_LINUX_ACCESS_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: case STREAM_ACL_SOLARIS_ACLENT: case STREAM_ACL_SOLARIS_ACE: case STREAM_ACL_AFS_TEXT: case STREAM_ACL_AIX_AIXC: case STREAM_ACL_AIX_NFS4: case STREAM_ACL_FREEBSD_NFS4_ACL: case STREAM_ACL_HURD_DEFAULT_ACL: case STREAM_ACL_HURD_ACCESS_ACL: if (extract) { wbuf = rec->data; wsize = rec->data_len; pm_strcpy(acl_data.last_fname, attr->fname); parse_acl_streams(jcr, &acl_data, rec->maskedStream, wbuf, wsize); } break; case STREAM_XATTR_HURD: case STREAM_XATTR_IRIX: case STREAM_XATTR_TRU64: case STREAM_XATTR_AIX: case STREAM_XATTR_OPENBSD: case STREAM_XATTR_SOLARIS_SYS: case STREAM_XATTR_SOLARIS: case STREAM_XATTR_DARWIN: case STREAM_XATTR_FREEBSD: case STREAM_XATTR_LINUX: case STREAM_XATTR_NETBSD: if (extract) { wbuf = rec->data; wsize = rec->data_len; pm_strcpy(xattr_data.last_fname, attr->fname); parse_xattr_streams(jcr, &xattr_data, rec->maskedStream, wbuf, wsize); } break; case STREAM_NDMP_SEPERATOR: break; default: /* If extracting, weird stream (not 1 or 2), close output file anyway */ if (extract) { if (!is_bopen(&bfd)) { Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n")); } set_attributes(jcr, attr, &bfd); extract = false; } Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), rec->Stream); break; } /* end switch */ return true; }
/* * Core interface function to lowlevel SCSI interface. */ static inline bool do_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len, int direction) { int rc; sg_io_hdr_t io_hdr; SCSI_PAGE_SENSE sense; bool opened_device = false; bool retval = false; /* * See if we need to open the device_name or if we got an open filedescriptor. */ if (fd == -1) { fd = open(device_name, O_RDWR | O_NONBLOCK | O_BINARY); if (fd < 0) { berrno be; Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to open %s: ERR=%s\n", device_name, be.bstrerror()); return false; } opened_device = true; } memset(&sense, 0, sizeof(sense)); memset(&io_hdr, 0, sizeof(io_hdr)); io_hdr.interface_id = 'S'; io_hdr.cmd_len = cdb_len; io_hdr.mx_sb_len = sizeof(sense); io_hdr.dxfer_direction = direction; io_hdr.dxfer_len = cmd_page_len; io_hdr.dxferp = (char *)cmd_page; io_hdr.cmdp = (unsigned char *)cdb; io_hdr.sbp = (unsigned char *)&sense; rc = ioctl(fd, SG_IO, &io_hdr); if (rc < 0) { berrno be; Emsg2(M_ERROR, 0, _("Unable to perform SG_IO ioctl on fd %d: ERR=%s\n"), fd, be.bstrerror()); Dmsg2(010, "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n", fd, be.bstrerror()); goto bail_out; } if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) { Emsg3(M_ERROR, 0, _("Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n"), io_hdr.info, io_hdr.masked_status, io_hdr.msg_status); Emsg2(M_ERROR, 0, _(" host status 0x%02x driver status 0x%02x\n"), io_hdr.host_status, io_hdr.driver_status ); Dmsg3(010, "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n", io_hdr.info, io_hdr.masked_status, io_hdr.msg_status); Dmsg2(010, " host status 0x%02x driver status 0x%02x\n", io_hdr.host_status, io_hdr.driver_status ); goto bail_out; } retval = true; bail_out: /* * See if we opened the device in this function, if so close it. */ if (opened_device) { close(fd); } return retval; }
/* * Core interface function to lowlevel SCSI interface. */ static inline bool do_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len, int flags) { int rc; scsireq_t req; SCSI_PAGE_SENSE *sense; bool opened_device = false; bool retval = false; /* * See if we need to open the device_name or if we got an open filedescriptor. */ if (fd == -1) { fd = open(device_name, O_RDWR | O_NONBLOCK| O_BINARY); if (fd < 0) { berrno be; Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to open %s: ERR=%s\n", device_name, be.bstrerror()); return false; } opened_device = true; } memset(&req, 0, sizeof(req)); memcpy(req.cmd, cdb, cdb_len); req.cmdlen = cdb_len; req.databuf = cmd_page; req.datalen = cmd_page_len; req.timeout = 15000 /* timeout (millisecs) */; req.flags = flags; req.senselen = sizeof(SCSI_PAGE_SENSE); rc = ioctl(fd, SCIOCCOMMAND, &req); if (rc < 0) { berrno be; Emsg2(M_ERROR, 0, _("Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n"), fd, be.bstrerror()); Dmsg2(010, "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n", fd, be.bstrerror()); goto bail_out; } switch (req.retsts) { case SCCMD_OK: retval = true; break; case SCCMD_SENSE: sense = req.sense; Emsg3(M_ERROR, 0, _("Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n"), LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); Dmsg3(010, "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n", LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); break; case SCCMD_TIMEOUT: Emsg1(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n"), devicename); Dmsg1(010, "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n", devicename); break; case SCCMD_BUSY: Emsg1(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned device is busy\n"), devicename); Dmsg1(010, "SCIOCCOMMAND ioctl on %s returned device is busy\n", devicename); break; case SCCMD_SENSE: break; default: Emsg2(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned unknown status %d\n"), device_name, req.retsts); Dmsg2(010, "SCIOCCOMMAND ioctl on %s returned unknown status %d\n", device_name, req.retsts); break; } bail_out: /* * See if we opened the device in this function, if so close it. */ if (opened_device) { close(fd); } return retval; }
/* * Core interface function to lowlevel SCSI interface. */ static inline bool do_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len, int flags) { int rc; struct uscsi_cmd my_cmd; SCSI_PAGE_SENSE sense; bool opened_device = false; bool retval = false; /* * See if we need to open the device_name or if we got an open filedescriptor. */ if (fd == -1) { fd = open(device_name, O_RDWR | O_NONBLOCK | O_BINARY); if (fd < 0) { berrno be; Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to open %s: ERR=%s\n", device_name, be.bstrerror()); return false; } opened_device = true; } memset(&sense, 0, sizeof(sense)); my_cmd.uscsi_flags = flags; my_cmd.uscsi_timeout = 15; /* Allow 15 seconds for completion */ my_cmd.uscsi_cdb = (char *)cdb; my_cmd.uscsi_cdblen = cdb_len; my_cmd.uscsi_bufaddr = (char *)cmd_page; my_cmd.uscsi_buflen = cmd_page_len; my_cmd.uscsi_rqlen = sizeof(sense); my_cmd.uscsi_rqbuf = (char *)&sense; rc = ioctl(fd, USCSICMD, &my_cmd); if (rc != 0) { berrno be; Emsg2(M_ERROR, 0, _("Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n"), fd, be.bstrerror()); Emsg3(M_ERROR, 0, _("Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n"), LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); Dmsg2(010, "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n", fd, be.bstrerror()); Dmsg3(010, "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n", LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); goto bail_out; } retval = true; bail_out: /* * See if we opened the device in this function, if so close it. */ if (opened_device) { close(fd); } return retval; }
/* * Drop to privilege new userid and new gid if non-NULL */ void drop(char *uname, char *gname) { #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H) struct passwd *passw = NULL; struct group *group = NULL; gid_t gid; uid_t uid; char username[1000]; Dmsg2(900, "uname=%s gname=%s\n", uname?uname:"NONE", gname?gname:"NONE"); if (!uname && !gname) { return; /* Nothing to do */ } if (uname) { if ((passw = getpwnam(uname)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not find userid=%s: ERR=%s\n"), uname, be.bstrerror()); } } else { if ((passw = getpwuid(getuid())) == NULL) { berrno be; Emsg1(M_ERROR_TERM, 0, _("Could not find password entry. ERR=%s\n"), be.bstrerror()); } else { uname = passw->pw_name; } } /* Any OS uname pointer may get overwritten, so save name, uid, and gid */ bstrncpy(username, uname, sizeof(username)); uid = passw->pw_uid; gid = passw->pw_gid; if (gname) { if ((group = getgrnam(gname)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not find group=%s: ERR=%s\n"), gname, be.bstrerror()); } gid = group->gr_gid; } if (initgroups(username, gid)) { berrno be; if (gname) { Emsg3(M_ERROR_TERM, 0, _("Could not initgroups for group=%s, userid=%s: ERR=%s\n"), gname, username, be.bstrerror()); } else { Emsg2(M_ERROR_TERM, 0, _("Could not initgroups for userid=%s: ERR=%s\n"), username, be.bstrerror()); } } if (gname) { if (setgid(gid)) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not set group=%s: ERR=%s\n"), gname, be.bstrerror()); } } if (setuid(uid)) { berrno be; Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), username); } #endif }