示例#1
0
int
cmd_view(int argc, char *argv[])
{
	struct smb_ctx sctx, *ctx = &sctx;
	struct smb_share_info_1 *rpbuf, *ep;
	char *cp;
	u_int16_t type;
	int error, opt, bufsize, i, entries, total;
	

	if (argc < 2)
		view_usage();
	if (smb_ctx_init(ctx, argc, argv, SMBL_VC, SMBL_VC, SMB_ST_ANY) != 0)
		exit(1);
	if (smb_ctx_readrc(ctx) != 0)
		exit(1);
	if (smb_rc)
		rc_close(smb_rc);
	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
		switch(opt){
		    case STDPARAM_ARGS:
			error = smb_ctx_opt(ctx, opt, optarg);
			if (error)
				exit(1);
			break;
		    default:
			view_usage();
			/*NOTREACHED*/
		}
	}
#ifdef APPLE
	if (loadsmbvfs())
		errx(EX_OSERR, "SMB filesystem is not available");
#endif
	smb_ctx_setshare(ctx, "IPC$", SMB_ST_ANY);
	if (smb_ctx_resolve(ctx) != 0)
		exit(1);
	error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
	if (error) {
		smb_error("could not login to server %s", error, ctx->ct_ssn.ioc_srvname);
		exit(1);
	}
	printf("Share        Type       Comment\n");
	printf("-------------------------------\n");
	bufsize = 0xffe0; /* samba notes win2k bug with 65535 */
	rpbuf = malloc(bufsize);
	error = smb_rap_NetShareEnum(ctx, 1, rpbuf, bufsize, &entries, &total);
	if (error &&
	    error != (SMB_ERROR_MORE_DATA | SMB_RAP_ERROR)) {
		smb_error("unable to list resources", error);
		exit(1);
	}
	for (ep = rpbuf, i = 0; i < entries; i++, ep++) {
		type = letohs(ep->shi1_type);

		cp = (char*)rpbuf + ep->shi1_remark;
		printf("%-12s %-10s %s\n", ep->shi1_netname,
		    shtype[min(type, sizeof shtype / sizeof(char *) - 1)],
		    ep->shi1_remark ? nls_str_toloc(cp, cp) : "");
	}
	printf("\n%d shares listed from %d available\n", entries, total);
	free(rpbuf);
	return 0;
}
示例#2
0
int
cmd_discon(int argc, char *argv[])
{
	struct smb_ctx *ctx;
	int error, opt;

	if (argc < 2)
		discon_usage();

	error = smb_ctx_alloc(&ctx);
	if (error != 0)
		return (error);

	error = smb_ctx_scan_argv(ctx, argc, argv,
	    SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
	if (error != 0)
		goto out;

	error = smb_ctx_readrc(ctx);
	if (error != 0)
		goto out;

	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
		if (opt == '?')
			discon_usage();
		error = smb_ctx_opt(ctx, opt, optarg);
		if (error != 0)
			goto out;
	}

	/*
	 * Resolve the server address,
	 * setup derived defaults.
	 */
	error = smb_ctx_resolve(ctx);
	if (error != 0)
		goto out;

	/*
	 * Have server, user, etc. from above:
	 * smb_ctx_scan_argv, option settings.
	 *
	 * Lookup a session without creating.
	 * (First part of smb_ctx_get_ssn)
	 * If we find the session, kill it.
	 */
	error = smb_ctx_findvc(ctx);
	if (error == ENOENT) {
		/* Already gone. We're done. */
		if (smb_debug)
			fprintf(stderr, "session not found\n");
		error = 0;
		goto out;
	}
	if (error == 0) {
		/* Found session.  Kill it. */
		error = smb_ctx_kill(ctx);
	}

	if (error != 0) {
		smb_error(gettext("//%s: discon failed"),
		    error, ctx->ct_fullserver);
	}

out:
	smb_ctx_free(ctx);
	return (error);
}
示例#3
0
int
main(int argc, char *argv[])
{
	struct iovec *iov;
	unsigned int iovlen;
	struct smb_ctx sctx, *ctx = &sctx;
	struct stat st;
#ifdef APPLE
	extern void dropsuid();
	extern int loadsmbvfs();
#else
	struct xvfsconf vfc;
#endif
	char *next, *p, *val;
	int opt, error, mntflags, caseopt, fd;
	uid_t uid;
	gid_t gid;
	mode_t dir_mode, file_mode;
	char errmsg[255] = { 0 };

	iov = NULL;
	iovlen = 0;
	fd = 0;
	uid = (uid_t)-1;
	gid = (gid_t)-1;
	caseopt = 0;
	file_mode = 0;
	dir_mode = 0;

#ifdef APPLE
	dropsuid();
#endif
	if (argc == 2) {
		if (strcmp(argv[1], "-h") == 0) {
			usage();
		}
	}
	if (argc < 3)
		usage();

#ifdef APPLE
	error = loadsmbvfs();
#else
	error = getvfsbyname(smbfs_vfsname, &vfc);
	if (error) {
		if (kldload(smbfs_vfsname) < 0)
			err(EX_OSERR, "kldload(%s)", smbfs_vfsname);
		error = getvfsbyname(smbfs_vfsname, &vfc);
	}
#endif
	if (error)
		errx(EX_OSERR, "SMB filesystem is not available");

	if (smb_lib_init() != 0)
		exit(1);

	mntflags = error = 0;

	caseopt = SMB_CS_NONE;

	if (smb_ctx_init(ctx, argc, argv, SMBL_SHARE, SMBL_SHARE, SMB_ST_DISK) != 0)
		exit(1);
	if (smb_ctx_readrc(ctx) != 0)
		exit(1);
	if (smb_rc)
		rc_close(smb_rc);

	while ((opt = getopt(argc, argv, STDPARAM_OPT"c:d:f:g:l:n:o:u:w:")) != -1) {
		switch (opt) {
		    case STDPARAM_ARGS:
			error = smb_ctx_opt(ctx, opt, optarg);
			if (error)
				exit(1);
			break;
		    case 'u': {
			struct passwd *pwd;

			pwd = isdigit(optarg[0]) ?
			    getpwuid(atoi(optarg)) : getpwnam(optarg);
			if (pwd == NULL)
				errx(EX_NOUSER, "unknown user '%s'", optarg);
			uid = pwd->pw_uid;
			break;
		    }
		    case 'g': {
			struct group *grp;

			grp = isdigit(optarg[0]) ?
			    getgrgid(atoi(optarg)) : getgrnam(optarg);
			if (grp == NULL)
				errx(EX_NOUSER, "unknown group '%s'", optarg);
			gid = grp->gr_gid;
			break;
		    }
		    case 'd':
			errno = 0;
			dir_mode = strtol(optarg, &next, 8);
			if (errno || *next != 0)
				errx(EX_DATAERR, "invalid value for directory mode");
			break;
		    case 'f':
			errno = 0;
			file_mode = strtol(optarg, &next, 8);
			if (errno || *next != 0)
				errx(EX_DATAERR, "invalid value for file mode");
			break;
		    case '?':
			usage();
			/*NOTREACHED*/
		    case 'n': {
			char *inp, *nsp;

			nsp = inp = optarg;
			while ((nsp = strsep(&inp, ",;:")) != NULL) {
				if (strcasecmp(nsp, "LONG") == 0) {
					build_iovec(&iov, &iovlen,
					    "nolong", NULL, 0);
				} else {
					errx(EX_DATAERR,
					    "unknown suboption '%s'", nsp);
				}
			}
			break;
		    };
		    case 'o':
			getmntopts(optarg, mopts, &mntflags, 0);
			p = strchr(optarg, '=');
			val = NULL;
			if (p != NULL) {
				*p = '\0';
				val = p + 1;
			}
			build_iovec(&iov, &iovlen, optarg, val, (size_t)-1);
			break;
		    case 'c':
			switch (optarg[0]) {
			    case 'l':
				caseopt |= SMB_CS_LOWER;
				break;
			    case 'u':
				caseopt |= SMB_CS_UPPER;
				break;
			    default:
		    		errx(EX_DATAERR, "invalid suboption '%c' for -c",
				    optarg[0]);
			}
			break;
		    default:
			usage();
		}
	}

	if (optind == argc - 2)
		optind++;
	
	if (optind != argc - 1)
		usage();
	realpath(argv[optind], mount_point);

	if (stat(mount_point, &st) == -1)
		err(EX_OSERR, "could not find mount point %s", mount_point);
	if (!S_ISDIR(st.st_mode)) {
		errno = ENOTDIR;
		err(EX_OSERR, "can't mount on %s", mount_point);
	}
/*
	if (smb_getextattr(mount_point, &einfo) == 0)
		errx(EX_OSERR, "can't mount on %s twice", mount_point);
*/
	if (uid == (uid_t)-1)
		uid = st.st_uid;
	if (gid == (gid_t)-1)
		gid = st.st_gid;
	if (file_mode == 0 )
		file_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
	if (dir_mode == 0) {
		dir_mode = file_mode;
		if (dir_mode & S_IRUSR)
			dir_mode |= S_IXUSR;
		if (dir_mode & S_IRGRP)
			dir_mode |= S_IXGRP;
		if (dir_mode & S_IROTH)
			dir_mode |= S_IXOTH;
	}
	/*
	 * For now, let connection be private for this mount
	 */
	ctx->ct_ssn.ioc_opt |= SMBVOPT_PRIVATE;
	ctx->ct_ssn.ioc_owner = ctx->ct_sh.ioc_owner = 0; /* root */
	ctx->ct_ssn.ioc_group = ctx->ct_sh.ioc_group = gid;
	opt = 0;
	if (dir_mode & S_IXGRP)
		opt |= SMBM_EXECGRP;
	if (dir_mode & S_IXOTH)
		opt |= SMBM_EXECOTH;
	ctx->ct_ssn.ioc_rights |= opt;
	ctx->ct_sh.ioc_rights |= opt;
	error = smb_ctx_resolve(ctx);
	if (error)
		exit(1);
	error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
	if (error) {
		exit(1);
	}

	fd = ctx->ct_fd;

	build_iovec(&iov, &iovlen, "fstype", strdup("smbfs"), -1);
	build_iovec(&iov, &iovlen, "fspath", mount_point, -1);
	build_iovec_argf(&iov, &iovlen, "fd", "%d", fd);
	build_iovec(&iov, &iovlen, "mountpoint", mount_point, -1);
	build_iovec_argf(&iov, &iovlen, "uid", "%d", uid);
	build_iovec_argf(&iov, &iovlen, "gid", "%d", gid);
	build_iovec_argf(&iov, &iovlen, "file_mode", "%d", file_mode);
	build_iovec_argf(&iov, &iovlen, "dir_mode", "%d", dir_mode);
	build_iovec_argf(&iov, &iovlen, "caseopt", "%d", caseopt);
	build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof errmsg); 

	error = nmount(iov, iovlen, mntflags);
	smb_ctx_done(ctx);
	if (error) {
		smb_error("mount error: %s %s", error, mount_point, errmsg);
		exit(1);
	}
	return 0;
}
示例#4
0
/*
 * Setup a new SMB client context.
 *
 * Get the SMB server's configuration stuff and
 * store it in the new client context object.
 */
int
smbrdr_ctx_new(struct smb_ctx **ctx_p, char *server,
	char *domain, char *user)
{
	struct smb_ctx *ctx = NULL;
	uchar_t nthash[SMBAUTH_HASH_SZ];
	int64_t lmcl;
	int authflags, err;

	assert(server != NULL);
	assert(domain != NULL);
	assert(user != NULL);

	if ((err = smb_ctx_alloc(&ctx)) != 0)
		return (NT_STATUS_NO_MEMORY);

	/*
	 * Set server, share, domain, user
	 * (in the ctx handle).
	 */
	(void) smb_ctx_setfullserver(ctx, server);
	(void) smb_ctx_setshare(ctx, "IPC$", USE_IPC);
	(void) smb_ctx_setdomain(ctx, domain, B_TRUE);
	(void) smb_ctx_setuser(ctx, user, B_TRUE);

	/*
	 * Set auth. info (hash) and type.
	 */
	if (user[0] == '\0') {
		authflags = SMB_AT_ANON;
	} else {
		(void) smb_config_getnum(SMB_CI_LM_LEVEL, &lmcl);
		if (lmcl <= 2) {
			/* Send NTLM */
			authflags = SMB_AT_NTLM1;
		} else {
			/* Send NTLMv2 */
			authflags = SMB_AT_NTLM2;
		}
		smb_ipc_get_passwd(nthash, sizeof (nthash));
		(void) smb_ctx_setpwhash(ctx, nthash, NULL);
	}
	(void) smb_ctx_setauthflags(ctx, authflags);

	/*
	 * Do lookup, connect, session setup, tree connect.
	 * Or find and reuse a session/tree, if one exists.
	 */
	if ((err = smb_ctx_resolve(ctx)) != 0) {
		err = NT_STATUS_BAD_NETWORK_PATH;
		goto errout;
	}
	if ((err = smb_ctx_get_ssn(ctx)) != 0) {
		err = NT_STATUS_NETWORK_ACCESS_DENIED;
		goto errout;
	}
	if ((err = smb_ctx_get_tree(ctx)) != 0) {
		err = NT_STATUS_BAD_NETWORK_NAME;
		goto errout;
	}

	/* Success! */
	*ctx_p = ctx;
	return (0);

errout:
	smb_ctx_free(ctx);
	return (err);
}
示例#5
0
int
cmd_view(int argc, char *argv[])
{
	struct smb_ctx *ctx;
	int error, err2, opt;

	if (argc < 2)
		view_usage();

	error = smb_ctx_alloc(&ctx);
	if (error)
		return (error);

	error = smb_ctx_scan_argv(ctx, argc, argv,
	    SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
	if (error)
		return (error);

	error = smb_ctx_readrc(ctx);
	if (error)
		return (error);

	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
		if (opt == '?')
			view_usage();
		error = smb_ctx_opt(ctx, opt, optarg);
		if (error)
			return (error);
	}

	smb_ctx_setshare(ctx, "IPC$", USE_IPC);

	/*
	 * Resolve the server address,
	 * setup derived defaults.
	 */
	error = smb_ctx_resolve(ctx);
	if (error)
		return (error);

	/*
	 * Have server, share, etc. from above:
	 * smb_ctx_scan_argv, option settings.
	 * Get the session and tree.
	 */
again:
	error = smb_ctx_get_ssn(ctx);
	if (error == EAUTH) {
		err2 = smb_get_authentication(ctx);
		if (err2 == 0)
			goto again;
	}
	if (error) {
		smb_error(gettext("//%s: login failed"),
		    error, ctx->ct_fullserver);
		return (error);
	}

	error = smb_ctx_get_tree(ctx);
	if (error) {
		smb_error(gettext("//%s/%s: tree connect failed"),
		    error, ctx->ct_fullserver, ctx->ct_origshare);
		return (error);
	}

	/*
	 * Have IPC$ tcon, now list shares.
	 * This prints its own errors.
	 */
	error = enum_shares(ctx);
	if (error)
		return (error);

	smb_ctx_free(ctx);
	return (0);
}
示例#6
0
文件: ctx.c 项目: execunix/vinos
int
smb_ctx_lookup(struct smb_ctx *ctx, int level, int flags)
{
	struct smbioc_lookup rq;
	int error;

	if ((ctx->ct_flags & SMBCF_RESOLVED) == 0) {
		smb_error("smb_ctx_lookup() data is not resolved", 0);
		return EINVAL;
	}
	if (ctx->ct_fd != -1) {
		smb_kops.ko_close(ctx->ct_fd);
		ctx->ct_fd = -1;
	}
	error = smb_ctx_gethandle(ctx);
	if (error) {
		smb_error("can't get handle to requester (no /dev/"NSMB_NAME"* device available)", 0);
		return EINVAL;
	}
	bzero(&rq, sizeof(rq));
	bcopy(&ctx->ct_ssn, &rq.ioc_ssn, sizeof(struct smbioc_ossn));
	bcopy(&ctx->ct_sh, &rq.ioc_sh, sizeof(struct smbioc_oshare));
	rq.ioc_flags = flags;
	rq.ioc_level = level;
	if (smb_kops.ko_ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) == -1) {
		error = errno;

		smb_kops.ko_close(ctx->ct_fd);
		ctx->ct_fd = -1;

		/*
		 * Fallback to *SMBSERVER as NetBIOS name. At least
		 * Windows NT and Windows XP require this (or valid
		 * NetBIOS server name), otherwise they refuse connection.
		 */
		if (smb_ctx_setserver(ctx, "*SMBSERVER") != 0)
			goto fail;

		error = smb_ctx_resolve(ctx);
		if (error)
			goto fail;

		error = smb_ctx_gethandle(ctx);
		if (error)
			goto fail;

		bcopy(&ctx->ct_ssn, &rq.ioc_ssn, sizeof(struct smbioc_ossn));

		if (smb_kops.ko_ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) != -1)
			goto success;
		error = errno;

	    fail:
		if (flags & SMBLK_CREATE)
			smb_error("unable to open connection", error);
		return error;
	}

    success:
	return 0;
}
示例#7
0
int
cmd_print(int argc, char *argv[])
{
	struct smb_ctx sctx, *ctx = &sctx;
	smbfh fh;
	off_t offset;
	char buf[8192];
	char *filename;
	char fnamebuf[256];
	int error, opt, i, file, count;

	if (argc < 2)
		view_usage();
	if (smb_ctx_init(ctx, argc, argv, SMBL_SHARE, SMBL_SHARE, SMB_ST_PRINTER) != 0)
		exit(1);
	if (smb_ctx_readrc(ctx) != 0)
		exit(1);
	if (smb_rc)
		rc_close(smb_rc);
	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
		switch(opt){
		    case STDPARAM_ARGS:
			error = smb_ctx_opt(ctx, opt, optarg);
			if (error)
				exit(1);
			break;
		    default:
			view_usage();
			/*NOTREACHED*/
		}
	}
	if (optind + 1 >= argc)
		print_usage();
	filename = argv[optind + 1];

	if (strcmp(filename, "-") == 0) {
		file = 0;	/* stdin */
		filename = "stdin";
	} else {
		file = open(filename, O_RDONLY, 0);
		if (file < 0) {
			smb_error("could not open file %s\n", errno, filename);
			exit(1);
		}
	}

	if (smb_ctx_resolve(ctx) != 0)
		exit(1);
	error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
	if (error) {
		smb_error("could not login to server %s", error, ctx->ct_ssn.ioc_srvname);
		exit(1);
	}
	snprintf(fnamebuf, sizeof(fnamebuf), "%s_%s_%s", ctx->ct_ssn.ioc_user,
	    ctx->ct_ssn.ioc_srvname, filename);
	error = smb_smb_open_print_file(ctx, 0, 1, fnamebuf, &fh);
	if (error) {
		smb_error("could not open print job", error);
		exit(1);
	}
	offset = 0;
	error = 0;
	for(;;) {
		count = read(file, buf, sizeof(buf));
		if (count == 0)
			break;
		if (count < 0) {
			error = errno;
			smb_error("error reading input file\n", error);
			break;
		}
		i = smb_write(ctx, fh, offset, count, buf);
		if (i < 0) {
			error = errno;
			smb_error("error writing spool file\n", error);
			break;
		}
		if (i != count) {
			smb_error("incomplete write to spool file\n", 0);
			error = EIO;
			break;
		}
		offset += count;
	}
	close(file);
	error = smb_smb_close_print_file(ctx, fh);
	if (error)
		smb_error("an error while closing spool file\n", error);
	return error ? 1 : 0;
}
示例#8
0
int
cmd_print(int argc, char *argv[])
{
	struct smb_ctx *ctx = NULL;
	char *filename;
	int error, opt;
	int file = -1;

	/* last arg is the print file. */
	if (argc < 3)
		print_usage();

	error = smb_ctx_alloc(&ctx);
	if (error)
		goto out;

	error = smb_ctx_scan_argv(ctx, argc-1, argv,
	    SMBL_SHARE, SMBL_SHARE, USE_SPOOLDEV);
	if (error)
		goto out;

	error = smb_ctx_readrc(ctx);
	if (error)
		goto out;

	while ((opt = getopt(argc-1, argv, STDPARAM_OPT)) != EOF) {
		if (opt == '?')
			print_usage();
		error = smb_ctx_opt(ctx, opt, optarg);
		if (error)
			goto out;
	}
	if (optind != argc-2)
		print_usage();
	filename = argv[argc-1];

	if (strcmp(filename, "-") == 0) {
		file = 0;	/* stdin */
		filename = "stdin";
	} else {
		file = open(filename, O_RDONLY, 0);
		if (file < 0) {
			smb_error("could not open file %s\n", errno, filename);
			exit(1);
		}
	}

	/*
	 * Resolve the server address,
	 * setup derived defaults.
	 */
	error = smb_ctx_resolve(ctx);
	if (error)
		goto out;

	/*
	 * Have server + share names, options etc.
	 * Get the session and tree.
	 */
again:
	error = smb_ctx_get_ssn(ctx);
	if (error == EAUTH) {
		int err2 = smb_get_authentication(ctx);
		if (err2 == 0)
			goto again;
	}
	if (error) {
		smb_error(gettext("//%s: login failed"),
		    error, ctx->ct_fullserver);
		goto out;
	}

	error = smb_ctx_get_tree(ctx);
	if (error) {
		smb_error(gettext("//%s/%s: tree connect failed"),
		    error, ctx->ct_fullserver, ctx->ct_origshare);
		goto out;
	}

	/*
	 * Have the printer share connection.
	 * Print the file.
	 */
	snprintf(titlebuf, sizeof (titlebuf), "%s %s",
	    ctx->ct_user, filename);

	error = print_file(ctx, titlebuf, file);


out:
	/* don't close stdin (file=0) */
	if (file > 0)
		close(file);

	smb_ctx_free(ctx);

	return (error);
}