From 4bdbd8bd0742c2c6e4ef65d7030a710412ad6234 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 18 Apr 2005 16:08:52 +0000 Subject: r6369: update release notes sync with SAMBA_3_0 (r6365). Getting ready for 3.0.15pre2 --- source/client/client.c | 57 +++++++-- source/client/clitar.c | 4 +- source/client/mount.cifs.c | 194 ++++++++++++++++++++++++++---- source/client/smbspool.c | 4 +- source/client/umount.cifs.c | 287 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 507 insertions(+), 39 deletions(-) create mode 100644 source/client/umount.cifs.c (limited to 'source/client') diff --git a/source/client/client.c b/source/client/client.c index 07eb02cf05c..be17488919d 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -29,6 +29,9 @@ #define REGISTER 0 #endif +extern BOOL AllowDebugChange; +extern BOOL override_logfile; +extern char tar_type; extern BOOL in_client; static int port = 0; pstring cur_dir = "\\"; @@ -257,6 +260,7 @@ static int do_cd(char *newdir) struct cli_state *targetcli; SMB_STRUCT_STAT sbuf; uint32 attributes; + int ret = 1; dos_format(newdir); @@ -302,21 +306,23 @@ static int do_cd(char *newdir) pstrcpy(cur_dir,saved_dir); goto out; } - } - else { + } else { pstrcat( targetpath, "\\" ); dos_clean_name( targetpath ); if ( !cli_chkpath(targetcli, targetpath) ) { d_printf("cd %s: %s\n", dname, cli_errstr(targetcli)); pstrcpy(cur_dir,saved_dir); + goto out; } } + ret = 0; + out: + pstrcpy(cd_path,cur_dir); - - return 0; + return ret; } /**************************************************************************** @@ -711,7 +717,7 @@ static int do_get(char *rname, char *lname, BOOL reget) struct timeval tp_start; int read_size = io_bufsize; uint16 attr; - size_t size; + SMB_OFF_T size; off_t start = 0; off_t nread = 0; int rc = 0; @@ -1135,7 +1141,7 @@ static int do_put(char *rname, char *lname, BOOL reput) { int fnum; XFILE *f; - size_t start = 0; + SMB_OFF_T start = 0; off_t nread = 0; char *buf = NULL; int maxwrite = io_bufsize; @@ -2235,6 +2241,25 @@ static int cmd_rename(void) return 0; } +/**************************************************************************** + Print the volume name. +****************************************************************************/ + +static int cmd_volume(void) +{ + fstring volname; + uint32 serial_num; + time_t create_date; + + if (!cli_get_fs_volume_info(cli, volname, &serial_num, &create_date)) { + d_printf("Errr %s getting volume info\n",cli_errstr(cli)); + return 1; + } + + d_printf("Volume: |%s| serial number 0x%x\n", volname, (unsigned int)serial_num); + return 0; +} + /**************************************************************************** Hard link files using the NT call. ****************************************************************************/ @@ -2748,6 +2773,7 @@ static struct {"tar",cmd_tar,"tar [IXFqbgNan] current directory to/from ",{COMPL_NONE,COMPL_NONE}}, {"tarmode",cmd_tarmode," tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}}, {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}}, + {"volume",cmd_volume,"print the volume name",{COMPL_NONE,COMPL_NONE}}, {"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}}, {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}}, {"listconnect",cmd_list_connect,"list open connections",{COMPL_NONE,COMPL_NONE}}, @@ -3147,7 +3173,13 @@ static int process(char *base_directory) return 1; } - if (*base_directory) do_cd(base_directory); + if (*base_directory) { + rc = do_cd(base_directory); + if (rc) { + cli_cm_shutdown(); + return rc; + } + } if (cmdstr) { rc = process_command_string(cmdstr); @@ -3210,7 +3242,13 @@ static int do_tar_op(char *base_directory) recurse=True; - if (*base_directory) do_cd(base_directory); + if (*base_directory) { + ret = do_cd(base_directory); + if (ret) { + cli_cm_shutdown(); + return ret; + } + } ret=process_tar(); @@ -3271,13 +3309,10 @@ static int do_message_op(void) int main(int argc,char *argv[]) { - extern BOOL AllowDebugChange; - extern BOOL override_logfile; pstring base_directory; int opt; pstring query_host; BOOL message = False; - extern char tar_type; pstring term_code; static const char *new_name_resolve_order = NULL; poptContext pc; diff --git a/source/client/clitar.c b/source/client/clitar.c index 524feca1d2a..b241bd0ec2a 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -44,7 +44,7 @@ static int clipfind(char **aret, int ret, char *tok); typedef struct file_info_struct file_info2; struct file_info_struct { - SMB_BIG_UINT size; + SMB_OFF_T size; uint16 mode; uid_t uid; gid_t gid; @@ -63,6 +63,7 @@ typedef struct { } stack; #define SEPARATORS " \t\n\r" +extern time_t newer_than; extern struct cli_state *cli; /* These defines are for the do_setrattr routine, to indicate @@ -1621,7 +1622,6 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind) return 0; } else { SMB_STRUCT_STAT stbuf; - extern time_t newer_than; if (sys_stat(argv[Optind], &stbuf) == 0) { newer_than = stbuf.st_mtime; diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c index 7b30b98fa7b..3145447cc4e 100755 --- a/source/client/mount.cifs.c +++ b/source/client/mount.cifs.c @@ -1,6 +1,6 @@ /* Mount helper utility for Linux CIFS VFS (virtual filesystem) client - Copyright (C) 2003 Steve French (sfrench@us.ibm.com) + Copyright (C) 2003,2005 Steve French (sfrench@us.ibm.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ #include #define MOUNT_CIFS_VERSION_MAJOR "1" -#define MOUNT_CIFS_VERSION_MINOR "6" +#define MOUNT_CIFS_VERSION_MINOR "7" #ifndef MOUNT_CIFS_VENDOR_SUFFIX #define MOUNT_CIFS_VENDOR_SUFFIX "" @@ -60,7 +60,8 @@ static int got_uid = 0; static int got_gid = 0; static int free_share_name = 0; static char * user_name = NULL; -char * mountpassword = NULL; +static char * mountpassword = NULL; +char * domain_name = NULL; /* BB finish BB @@ -72,6 +73,9 @@ char * mountpassword = NULL; BB end finish BB */ +static char * check_for_domain(char **); + + static void mount_cifs_usage(void) { printf("\nUsage: %s -o \n", thisprogram); @@ -79,11 +83,11 @@ static void mount_cifs_usage(void) printf(" to a local directory.\n\nOptions:\n"); printf("\tuser=\n\tpass=\n\tdom=\n"); printf("\nLess commonly used options:"); - printf("\n\tcredentials=,guest,perm,noperm,setuids,nosetuids,\n\trw,ro,sep=,iocharset=,suid,nosuid,exec,noexec,directio"); - printf("\n\nOptions not needed for servers supporting CIFS Unix extensions (e.g. most Samba versions):"); + printf("\n\tcredentials=,guest,perm,noperm,setuids,nosetuids,rw,ro,\n\tsep=,iocharset=,suid,nosuid,exec,noexec,serverino,\n\tdirectio"); + printf("\n\nOptions not needed for servers supporting CIFS Unix extensions\n\t(e.g. most Samba versions):"); printf("\n\tuid=,gid=,dir_mode=,file_mode="); printf("\n\nRarely used options:"); - printf("\n\tport=,rsize=,wsize=,unc=,ip=,dev,nodev"); + printf("\n\tport=,rsize=,wsize=,unc=,ip=,\n\tdev,nodev,nouser_xattr,netbiosname,hard,soft,intr,nointr,noacl"); printf("\n\nOptions are described in more detail in the manual page"); printf("\n\tman 8 mount.cifs\n"); printf("\nTo display the version number of the mount helper:"); @@ -107,7 +111,7 @@ static char * getusername(void) { return username; } -char * parse_cifs_url(char * unc_name) +static char * parse_cifs_url(char * unc_name) { printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n",unc_name); return NULL; @@ -264,7 +268,9 @@ static int parse_options(char * options, int * filesys_flags) data = options; if(verboseflag) - printf("\n parsing options: %s", options); + printf("parsing options: %s\n", options); + + /* BB fixme check for separator override BB */ /* while ((data = strsep(&options, ",")) != NULL) { */ while(data != NULL) { @@ -276,15 +282,12 @@ static int parse_options(char * options, int * filesys_flags) /* data = next keyword */ /* value = next value ie stuff after equal sign */ - next_keyword = strchr(data,','); + next_keyword = strchr(data,','); /* BB handle sep= */ /* temporarily null terminate end of keyword=value pair */ if(next_keyword) *next_keyword = 0; - /* if (!*data) - continue; */ - /* temporarily null terminate keyword to make keyword and value distinct */ if ((value = strchr(data, '=')) != NULL) { *value = '\0'; @@ -298,6 +301,7 @@ static int parse_options(char * options, int * filesys_flags) } else if (strncmp(data, "user_xattr",10) == 0) { /* do nothing - need to skip so not parsed as user name */ } else if (strncmp(data, "user", 4) == 0) { + if (!value || !*value) { if(data[4] == '\0') { if(verboseflag) @@ -308,7 +312,6 @@ static int parse_options(char * options, int * filesys_flags) data[1] = ','; data[2] = ','; data[3] = ','; - /* BB remove it from mount line so as not to confuse kernel code */ } else { printf("username specified with no parameter\n"); return 1; /* needs_arg; */ @@ -334,6 +337,13 @@ static int parse_options(char * options, int * filesys_flags) } } } + /* this is only case in which the user + name buf is not malloc - so we have to + check for domain name embedded within + the user name here since the later + call to check_for_domain will not be + invoked */ + domain_name = check_for_domain(&value); } else { printf("username too long\n"); return 1; @@ -516,15 +526,135 @@ static int parse_options(char * options, int * filesys_flags) /* put previous overwritten comma back */ if(next_keyword) - *next_keyword = ','; + *next_keyword = ','; /* BB handle sep= */ else data = NULL; } return 0; } +/* replace all (one or more) commas with double commas */ +static void check_for_comma(char ** ppasswrd) +{ + char *new_pass_buf; + char *pass; + int i,j; + int number_of_commas = 0; + int len = strlen(*ppasswrd); + + if(ppasswrd == NULL) + return; + else + (pass = *ppasswrd); + + for(i=0;i 64) { + /* would otherwise overflow the mount options buffer */ + printf("\nInvalid password. Password contains too many commas.\n"); + return; + } + + new_pass_buf = malloc(len+number_of_commas+1); + if(new_pass_buf == NULL) + return; + + for(i=0,j=0;i= original_len) { + /* should not happen */ + return domainnm; + } + + for(i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define UNMOUNT_CIFS_VERSION_MAJOR "0" +#define UNMOUNT_CIFS_VERSION_MINOR "2" + +#ifndef UNMOUNT_CIFS_VENDOR_SUFFIX +#define UNMOUNT_CIFS_VENDOR_SUFFIX "" +#endif + +#ifndef MNT_DETACH +#define MNT_DETACH 0x02 +#endif + +#ifndef MNT_EXPIRE +#define MNT_EXPIRE 0x04 +#endif + +#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) +#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDU */ + +static struct option longopts[] = { + { "all", 0, NULL, 'a' }, + { "help",0, NULL, 'h' }, + { "read-only", 0, NULL, 'r' }, + { "ro", 0, NULL, 'r' }, + { "verbose", 0, NULL, 'v' }, + { "version", 0, NULL, 'V' }, + { "expire", 0, NULL, 'e' }, + { "force", 0, 0, 'f' }, + { "lazy", 0, 0, 'l' }, + { "no-mtab", 0, 0, 'n' }, + { NULL, 0, NULL, 0 } +}; + +char * thisprogram; +int verboseflg = 0; + +static void umount_cifs_usage(void) +{ + printf("\nUsage: %s \n", thisprogram); + printf("\nUnmount the specified directory\n"); + printf("\nLess commonly used options:"); + printf("\n\t-r\tIf mount fails, retry with readonly remount."); + printf("\n\t-n\tDo not write to mtab."); + printf("\n\t-f\tAttempt a forced unmount, even if the fs is busy."); + printf("\n\t-l\tAttempt lazy unmount, Unmount now, cleanup later."); + printf("\n\t-v\tEnable verbose mode (may be useful for debugging)."); + printf("\n\t-h\tDisplay this help."); + printf("\n\nOptions are described in more detail in the manual page"); + printf("\n\tman 8 umount.cifs\n"); + printf("\nTo display the version number of the cifs umount utility:"); + printf("\n\t%s -V\n",thisprogram); +} + +static int umount_check_perm(char * dir) +{ + int fileid; + int rc; + + /* presumably can not chdir into the target as we do on mount */ + + fileid = open(dir, O_RDONLY | O_DIRECTORY | O_NOFOLLOW, 0); + if(fileid == -1) { + if(verboseflg) + printf("error opening mountpoint %d %s",errno,strerror(errno)); + return errno; + } + + rc = ioctl(fileid, CIFS_IOC_CHECKUMOUNT, NULL); + + if(verboseflg) + printf("ioctl returned %d with errno %d %s\n",rc,errno,strerror(errno)); + + if(rc == ENOTTY) + printf("user unmounting via %s is an optional feature of the cifs filesystem driver (cifs.ko)\n\tand requires cifs.ko version 1.32 or later\n",thisprogram); + else if (rc > 0) + printf("user unmount of %s failed with %d %s\n",dir,errno,strerror(errno)); + close(fileid); + + return rc; +} + +int main(int argc, char ** argv) +{ + int c; + int rc; + int flags = 0; + int nomtab = 0; + int retry_remount = 0; + struct mntent mountent; + struct statfs statbuf; + char * mountpoint; + FILE * pmntfile; + + if(argc && argv) { + thisprogram = argv[0]; + } else { + umount_cifs_usage(); + return -EINVAL; + } + + if(argc < 2) { + umount_cifs_usage(); + return -EINVAL; + } + + if(thisprogram == NULL) + thisprogram = "umount.cifs"; + + /* add sharename in opts string as unc= parm */ + + while ((c = getopt_long (argc, argv, "afhilnrvV", + longopts, NULL)) != -1) { + switch (c) { +/* No code to do the following option yet */ +/* case 'a': + ++umount_all; + break; */ + case '?': + case 'h': /* help */ + umount_cifs_usage(); + exit(1); + case 'n': + ++nomtab; + break; + case 'f': + flags |= MNT_FORCE; + break; + case 'l': + flags |= MNT_DETACH; /* lazy unmount */ + break; + case 'e': + flags |= MNT_EXPIRE; /* gradually timeout */ + break; + case 'r': + ++retry_remount; + break; + case 'v': + ++verboseflg; + break; + case 'V': + printf ("umount.cifs version: %s.%s%s\n", + UNMOUNT_CIFS_VERSION_MAJOR, + UNMOUNT_CIFS_VERSION_MINOR, + UNMOUNT_CIFS_VENDOR_SUFFIX); + exit (0); + default: + printf("unknown unmount option %c\n",c); + umount_cifs_usage(); + exit(1); + } + } + + /* move past the umount options */ + argv += optind; + argc -= optind; + + mountpoint = argv[0]; + + if((argc < 1) || (argv[0] == NULL)) { + printf("\nMissing name of unmount directory\n"); + umount_cifs_usage(); + return -EINVAL; + } + + if(verboseflg) + printf("optind %d unmount dir %s\n",optind, mountpoint); + + /* check if running effectively root */ + if(geteuid() != 0) { + printf("Trying to unmount when %s not installed suid\n",thisprogram); + if(verboseflg) + printf("euid = %d\n",geteuid()); + return -EACCES; + } + + /* fixup path if needed */ + + /* make sure that this is a cifs filesystem */ + rc = statfs(mountpoint, &statbuf); + + if(rc || (statbuf.f_type != CIFS_MAGIC_NUMBER)) { + printf("Wrong filesystem. This utility only unmounts cifs filesystems.\n"); + return -EINVAL; + } + + /* check if our uid was the one who mounted */ + rc = umount_check_perm(mountpoint); + if (rc) { + printf("Not permitted to unmount\n"); + return rc; + } + + if(umount2(mountpoint, flags)) { + /* remember to kill daemon on error */ + switch (errno) { + case 0: + printf("unmount failed but no error number set\n"); + break; + default: + printf("unmount error %d = %s\n",errno,strerror(errno)); + } + printf("Refer to the umount.cifs(8) manual page (e.g.man 8 umount.cifs)\n"); + return -1; + } else { + pmntfile = setmntent(MOUNTED, "a+"); + if(pmntfile) { +/* mountent.mnt_fsname = share_name; + mountent.mnt_dir = mountpoint; + mountent.mnt_type = "cifs"; + mountent.mnt_opts = malloc(220); + if(mountent.mnt_opts) { + char * mount_user = getusername(); + memset(mountent.mnt_opts,0,200); + if(flags & MS_RDONLY) + strcat(mountent.mnt_opts,"ro"); + else + strcat(mountent.mnt_opts,"rw"); + if(flags & MS_MANDLOCK) + strcat(mountent.mnt_opts,",mand"); + else + strcat(mountent.mnt_opts,",nomand"); + if(flags & MS_NOEXEC) + strcat(mountent.mnt_opts,",noexec"); + if(flags & MS_NOSUID) + strcat(mountent.mnt_opts,",nosuid"); + if(flags & MS_NODEV) + strcat(mountent.mnt_opts,",nodev"); + if(flags & MS_SYNCHRONOUS) + strcat(mountent.mnt_opts,",synch"); + if(mount_user) { + if(getuid() != 0) { + strcat(mountent.mnt_opts,",user="); + strcat(mountent.mnt_opts,mount_user); + } + free(mount_user); + } + } + mountent.mnt_freq = 0; + mountent.mnt_passno = 0; + rc = addmntent(pmntfile,&mountent); + endmntent(pmntfile); + if(mountent.mnt_opts) + free(mountent.mnt_opts);*/ + } else { + printf("could not update mount table\n"); + } + } + + return 0; +} + -- cgit