1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-27 14:04:05 +03:00
Michael Warfield cdaa53e3ef Two changes in this ball...
1) Changes to smbmnt.c, smbmount.c, and smbumount.c allow them to compile on
both RedHat 4.x (libc 4.x) systems and RedHat 5.x (glibc 2) systems.

2) Changes to Makefile.in and configure.in (and subsequently configure) are to
configure for smbmount, smbumount, and smbmnt to compile.

This adds a "--with(out)-smbmount" option to configure.  Sanity checking is
not present yet.  You can specify this if you are not on linux, it just
won't compile.
(This used to be commit 8a4730f61923577b0bd9e09ef1a00538f7dfb0de)
1998-09-28 19:18:21 +00:00

286 lines
7.1 KiB
C

/*
* smbmount.c
*
* Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
*
*/
#include "includes.h"
#include <mntent.h>
#include <asm/types.h>
#include <asm/posix_types.h>
#include <linux/smb.h>
#include <linux/smb_mount.h>
#include <asm/unistd.h>
#ifndef MS_MGC_VAL
/* This may look strange but MS_MGC_VAL is what we are looking for and
is what we need from <linux/fs.h> under libc systems and is
provided in standard includes on glibc systems. So... We
switch on what we need... */
#include <linux/fs.h>
#endif
static char *progname;
static void
usage(void)
{
printf("usage: %s mount-point [options]\n", progname);
printf("Try `%s -h' for more information\n", progname);
}
static void
help(void)
{
printf("\n");
printf("usage: %s mount-point [options]\n", progname);
printf("-u uid uid the mounted files get\n"
"-g gid gid the mounted files get\n"
"-f mode permission the files get (octal notation)\n"
"-d mode permission the dirs get (octal notation)\n"
"-P pid connection handler's pid\n\n"
"-s share share name on server\n\n"
"-h print this help text\n");
}
static int
parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
{
int opt;
struct passwd *pwd;
struct group *grp;
while ((opt = getopt (argc, argv, "u:g:f:d:s:")) != EOF)
{
switch (opt)
{
case 'u':
if (isdigit(optarg[0]))
{
data->uid = atoi(optarg);
}
else
{
pwd = getpwnam(optarg);
if (pwd == NULL)
{
fprintf(stderr, "Unknown user: %s\n",
optarg);
return 1;
}
data->uid = pwd->pw_uid;
}
break;
case 'g':
if (isdigit(optarg[0]))
{
data->gid = atoi(optarg);
}
else
{
grp = getgrnam(optarg);
if (grp == NULL)
{
fprintf(stderr, "Unknown group: %s\n",
optarg);
return 1;
}
data->gid = grp->gr_gid;
}
break;
case 'f':
data->file_mode = strtol(optarg, NULL, 8);
break;
case 'd':
data->dir_mode = strtol(optarg, NULL, 8);
break;
case 's':
*share = optarg;
break;
default:
return -1;
}
}
return 0;
}
static char *
fullpath(const char *p)
{
char path[MAXPATHLEN];
if (strlen(p) > MAXPATHLEN-1)
{
return NULL;
}
if (realpath(p, path) == NULL)
{
return strdup(p);
}
return strdup(path);
}
/* Check whether user is allowed to mount on the specified mount point */
static int
mount_ok(SMB_STRUCT_STAT *st)
{
if (!S_ISDIR(st->st_mode))
{
errno = ENOTDIR;
return -1;
}
if ( (getuid() != 0)
&& ( (getuid() != st->st_uid)
|| ((st->st_mode & S_IRWXU) != S_IRWXU)))
{
errno = EPERM;
return -1;
}
return 0;
}
int
main(int argc, char *argv[])
{
char *mount_point, *share_name = NULL;
FILE *mtab;
int fd, um;
unsigned int flags;
struct smb_mount_data data;
SMB_STRUCT_STAT st;
struct mntent ment;
progname = argv[0];
memset(&data, 0, sizeof(struct smb_mount_data));
if ( (argc == 2)
&& (argv[1][0] == '-')
&& (argv[1][1] == 'h')
&& (argv[1][2] == '\0'))
{
help();
return 0;
}
if (geteuid() != 0) {
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
if (argc < 2)
{
usage();
return 1;
}
mount_point = argv[1];
argv += 1;
argc -= 1;
if (sys_stat(mount_point, &st) == -1) {
fprintf(stderr, "could not find mount point %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
if (mount_ok(&st) != 0) {
fprintf(stderr, "cannot mount on %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
data.version = SMB_MOUNT_VERSION;
/* getuid() gives us the real uid, who may umount the fs */
data.mounted_uid = getuid();
data.uid = getuid();
data.gid = getgid();
um = umask(0);
umask(um);
data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
data.dir_mode = 0;
if (parse_args(argc, argv, &data, &share_name) != 0) {
usage();
return -1;
}
if (data.dir_mode == 0) {
data.dir_mode = data.file_mode;
if ((data.dir_mode & S_IRUSR) != 0)
data.dir_mode |= S_IXUSR;
if ((data.dir_mode & S_IRGRP) != 0)
data.dir_mode |= S_IXGRP;
if ((data.dir_mode & S_IROTH) != 0)
data.dir_mode |= S_IXOTH;
}
flags = MS_MGC_VAL;
if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
{
perror("mount error");
printf("Please refer to the smbmnt(8) manual page\n");
return -1;
}
ment.mnt_fsname = share_name ? share_name : "none";
ment.mnt_dir = fullpath(mount_point);
ment.mnt_type = "smbfs";
ment.mnt_opts = "";
ment.mnt_freq = 0;
ment.mnt_passno= 0;
mount_point = ment.mnt_dir;
if (mount_point == NULL)
{
fprintf(stderr, "Mount point too long\n");
return -1;
}
if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
{
fprintf(stderr, "Can't get "MOUNTED"~ lock file");
return 1;
}
close(fd);
if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
{
fprintf(stderr, "Can't open " MOUNTED);
return 1;
}
if (addmntent(mtab, &ment) == 1)
{
fprintf(stderr, "Can't write mount entry");
return 1;
}
if (fchmod(fileno(mtab), 0644) == -1)
{
fprintf(stderr, "Can't set perms on "MOUNTED);
return 1;
}
endmntent(mtab);
if (unlink(MOUNTED"~") == -1)
{
fprintf(stderr, "Can't remove "MOUNTED"~");
return 1;
}
return 0;
}