diff options
author | Andrew Tridgell <tridge@samba.org> | 1999-12-13 13:27:58 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1999-12-13 13:27:58 +0000 |
commit | 453a822a76780063dff23526c35408866d0c0154 (patch) | |
tree | 804feffcd5e60153e27d3ca2b007021e66e5bd0a /source/client/smbmnt.c | |
parent | 054195df9b6187c663ede5cf4489499abbdc29fc (diff) | |
download | samba-453a822a76780063dff23526c35408866d0c0154.tar.gz samba-453a822a76780063dff23526c35408866d0c0154.tar.xz samba-453a822a76780063dff23526c35408866d0c0154.zip |
first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
Diffstat (limited to 'source/client/smbmnt.c')
-rw-r--r-- | source/client/smbmnt.c | 201 |
1 files changed, 92 insertions, 109 deletions
diff --git a/source/client/smbmnt.c b/source/client/smbmnt.c index fa3cacb8640..b7e30c3967f 100644 --- a/source/client/smbmnt.c +++ b/source/client/smbmnt.c @@ -1,7 +1,8 @@ /* - * smbmount.c + * smbmnt.c * * Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke + * extensively modified by Tridge * */ @@ -23,27 +24,24 @@ #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 uid_t mount_uid; +static gid_t mount_gid; +static int mount_ro; +static unsigned mount_fmask; +static unsigned mount_dmask; +static int user_mount; 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" + printf("usage: smbmnt mount-point [options]\n"); + printf("-s share share name on server\n" + "-r mount read-only\n" + "-u uid mount as uid\n" + "-g gid mount as gid\n" + "-f mask permission mask for files\n" + "-d mask permission mask for directories\n" "-h print this help text\n"); } @@ -51,55 +49,32 @@ 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) + while ((opt = getopt (argc, argv, "s:u:g:rf:d:")) != EOF) { switch (opt) { + case 's': + *share = optarg; + break; 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; - } + if (!user_mount) { + mount_uid = strtol(optarg, NULL, 0); + } 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; - } + if (!user_mount) { + mount_gid = strtol(optarg, NULL, 0); + } + break; + case 'r': + mount_ro = 1; break; case 'f': - data->file_mode = strtol(optarg, NULL, 8); + mount_fmask = strtol(optarg, NULL, 8); break; case 'd': - data->dir_mode = strtol(optarg, NULL, 8); - break; - case 's': - *share = optarg; + mount_dmask = strtol(optarg, NULL, 8); break; default: return -1; @@ -114,32 +89,39 @@ fullpath(const char *p) { char path[MAXPATHLEN]; - if (strlen(p) > MAXPATHLEN-1) - { + if (strlen(p) > MAXPATHLEN-1) { return NULL; } - if (realpath(p, path) == NULL) - { - return strdup(p); + if (realpath(p, path) == NULL) { + fprintf(stderr,"Failed to find real path for mount point\n"); + exit(1); } return strdup(path); } -/* Check whether user is allowed to mount on the specified mount point */ -static int -mount_ok(SMB_STRUCT_STAT *st) +/* Check whether user is allowed to mount on the specified mount point. If it's + OK then we change into that directory - this prevents race conditions */ +static int mount_ok(char *mount_point) { - if (!S_ISDIR(st->st_mode)) - { + SMB_STRUCT_STAT st; + + if (chdir(mount_point) != 0) { + return -1; + } + + if (sys_stat(".", &st) != 0) { + return -1; + } + + if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR; return -1; } - - if ( (getuid() != 0) - && ( (getuid() != st->st_uid) - || ((st->st_mode & S_IRWXU) != S_IRWXU))) - { + + if ((getuid() != 0) && + ((getuid() != st.st_uid) || + ((st.st_mode & S_IRWXU) != S_IRWXU))) { errno = EPERM; return -1; } @@ -147,53 +129,48 @@ mount_ok(SMB_STRUCT_STAT *st) return 0; } -int -main(int argc, char *argv[]) + int main(int argc, char *argv[]) { char *mount_point, *share_name = NULL; FILE *mtab; - int fd, um; + int fd; 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')) - { + if (argc < 2) { + help(); + exit(1); + } + + if (argv[1][0] == '-') { help(); - return 0; + exit(1); + } + + if (getuid() != 0) { + user_mount = 1; } if (geteuid() != 0) { - fprintf(stderr, "%s must be installed suid root\n", progname); + fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid()); exit(1); } - if (argc < 2) - { - usage(); - return 1; - } + mount_uid = getuid(); + mount_gid = getgid(); + mount_fmask = umask(0); + umask(mount_fmask); + mount_fmask = ~mount_fmask; - mount_point = argv[1]; + mount_point = fullpath(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) { + if (mount_ok(mount_point) != 0) { fprintf(stderr, "cannot mount on %s: %s\n", mount_point, strerror(errno)); exit(1); @@ -204,19 +181,17 @@ main(int argc, char *argv[]) /* 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(); + help(); return -1; } - if (data.dir_mode == 0) { + data.uid = mount_uid; + data.gid = mount_gid; + data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask; + data.dir_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask; + + if (mount_dmask == 0) { data.dir_mode = data.file_mode; if ((data.dir_mode & S_IRUSR) != 0) data.dir_mode |= S_IXUSR; @@ -228,15 +203,23 @@ main(int argc, char *argv[]) flags = MS_MGC_VAL; - if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0) + if (mount_ro) flags |= MS_RDONLY; + + if (mount(share_name, ".", "smbfs", flags, (char *)&data) < 0) { - perror("mount error"); - printf("Please refer to the smbmnt(8) manual page\n"); + switch (errno) { + case ENODEV: + fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n"); + break; + default: + perror("mount error"); + } + fprintf(stderr, "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_dir = mount_point; ment.mnt_type = "smbfs"; ment.mnt_opts = ""; ment.mnt_freq = 0; |