[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1970-g8d033ec

Jelmer Vernooij jelmer at samba.org
Tue Jun 2 21:25:27 GMT 2009


The branch, master has been updated
       via  8d033ec0d115fe2cdd9bf1fa9758cc0994f5b6f0 (commit)
      from  e0a6a344be326c58dc9307f286226f76f15f78e8 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 8d033ec0d115fe2cdd9bf1fa9758cc0994f5b6f0
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Jun 2 23:07:59 2009 +0200

    Move mount.cifs/umount.cifs to the top level and remove the outdated copy
    in Samba 4.

-----------------------------------------------------------------------

Summary of changes:
 {source3/client => client}/cifs.upcall.c |    0 
 {source3/client => client}/cifs_spnego.h |    0 
 client/mount.cifs.c                      | 1539 ++++++++++++++++++++++++++++++
 {source3/client => client}/mount.h       |    0 
 {source3/client => client}/mtab.c        |    0 
 client/umount.cifs.c                     |  405 ++++++++
 source3/Makefile.in                      |    6 +-
 source3/client/mount.cifs.c              | 1539 ------------------------------
 source3/client/umount.cifs.c             |  405 --------
 source4/build/m4/public.m4               |    2 +-
 source4/client/config.m4                 |   13 +
 source4/client/config.mk                 |   17 +
 source4/client/mount.cifs.c              |  559 -----------
 source4/configure.ac                     |    1 +
 14 files changed, 1979 insertions(+), 2507 deletions(-)
 rename {source3/client => client}/cifs.upcall.c (100%)
 rename {source3/client => client}/cifs_spnego.h (100%)
 create mode 100644 client/mount.cifs.c
 rename {source3/client => client}/mount.h (100%)
 rename {source3/client => client}/mtab.c (100%)
 create mode 100644 client/umount.cifs.c
 delete mode 100644 source3/client/mount.cifs.c
 delete mode 100644 source3/client/umount.cifs.c
 create mode 100644 source4/client/config.m4
 delete mode 100644 source4/client/mount.cifs.c


Changeset truncated at 500 lines:

diff --git a/source3/client/cifs.upcall.c b/client/cifs.upcall.c
similarity index 100%
rename from source3/client/cifs.upcall.c
rename to client/cifs.upcall.c
diff --git a/source3/client/cifs_spnego.h b/client/cifs_spnego.h
similarity index 100%
rename from source3/client/cifs_spnego.h
rename to client/cifs_spnego.h
diff --git a/client/mount.cifs.c b/client/mount.cifs.c
new file mode 100644
index 0000000..1b94486
--- /dev/null
+++ b/client/mount.cifs.c
@@ -0,0 +1,1539 @@
+/* 
+   Mount helper utility for Linux CIFS VFS (virtual filesystem) client
+   Copyright (C) 2003,2008 Steve French  (sfrench at us.ibm.com)
+   Copyright (C) 2008 Jeremy Allison (jra at samba.org)
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <getopt.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <mntent.h>
+#include <fcntl.h>
+#include <limits.h>
+#include "mount.h"
+
+#define MOUNT_CIFS_VERSION_MAJOR "1"
+#define MOUNT_CIFS_VERSION_MINOR "12"
+
+#ifndef MOUNT_CIFS_VENDOR_SUFFIX
+ #ifdef _SAMBA_BUILD_
+  #include "version.h"
+  #ifdef SAMBA_VERSION_VENDOR_SUFFIX
+   #define MOUNT_CIFS_VENDOR_SUFFIX "-"SAMBA_VERSION_OFFICIAL_STRING"-"SAMBA_VERSION_VENDOR_SUFFIX
+  #else
+   #define MOUNT_CIFS_VENDOR_SUFFIX "-"SAMBA_VERSION_OFFICIAL_STRING
+  #endif /* SAMBA_VERSION_OFFICIAL_STRING and SAMBA_VERSION_VENDOR_SUFFIX */
+ #else
+   #define MOUNT_CIFS_VENDOR_SUFFIX ""
+ #endif /* _SAMBA_BUILD_ */
+#endif /* MOUNT_CIFS_VENDOR_SUFFIX */
+
+#ifdef _SAMBA_BUILD_
+#include "include/config.h"
+#endif
+
+#ifndef MS_MOVE 
+#define MS_MOVE 8192 
+#endif 
+
+#ifndef MS_BIND
+#define MS_BIND 4096
+#endif
+
+#define MAX_UNC_LEN 1024
+
+#define CONST_DISCARD(type, ptr)      ((type) ((void *) (ptr)))
+
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+#endif
+
+#define MOUNT_PASSWD_SIZE 128
+#define DOMAIN_SIZE 64
+
+/* currently maximum length of IPv6 address string */
+#define MAX_ADDRESS_LEN INET6_ADDRSTRLEN
+
+const char *thisprogram;
+int verboseflag = 0;
+int fakemnt = 0;
+static int got_password = 0;
+static int got_user = 0;
+static int got_domain = 0;
+static int got_ip = 0;
+static int got_unc = 0;
+static int got_uid = 0;
+static int got_gid = 0;
+static char * user_name = NULL;
+static char * mountpassword = NULL;
+char * domain_name = NULL;
+char * prefixpath = NULL;
+
+/* glibc doesn't have strlcpy, strlcat. Ensure we do. JRA. We
+ * don't link to libreplace so need them here. */
+
+/* like strncpy but does not 0 fill the buffer and always null
+ *    terminates. bufsize is the size of the destination buffer */
+
+#ifndef HAVE_STRLCPY
+static size_t strlcpy(char *d, const char *s, size_t bufsize)
+{
+	size_t len = strlen(s);
+	size_t ret = len;
+	if (bufsize <= 0) return 0;
+	if (len >= bufsize) len = bufsize-1;
+	memcpy(d, s, len);
+	d[len] = 0;
+	return ret;
+}
+#endif
+
+/* like strncat but does not 0 fill the buffer and always null
+ *    terminates. bufsize is the length of the buffer, which should
+ *       be one more than the maximum resulting string length */
+
+#ifndef HAVE_STRLCAT
+static size_t strlcat(char *d, const char *s, size_t bufsize)
+{
+	size_t len1 = strlen(d);
+	size_t len2 = strlen(s);
+	size_t ret = len1 + len2;
+
+	if (len1+len2 >= bufsize) {
+		if (bufsize < (len1+1)) {
+			return ret;
+		}
+		len2 = bufsize - (len1+1);
+	}
+	if (len2 > 0) {
+		memcpy(d+len1, s, len2);
+		d[len1+len2] = 0;
+	}
+	return ret;
+}
+#endif
+
+/* BB finish BB
+
+        cifs_umount
+        open nofollow - avoid symlink exposure? 
+        get owner of dir see if matches self or if root
+        call system(umount argv) etc.
+                
+BB end finish BB */
+
+static char * check_for_domain(char **);
+
+
+static void mount_cifs_usage(void)
+{
+	printf("\nUsage:  %s <remotetarget> <dir> -o <options>\n", thisprogram);
+	printf("\nMount the remote target, specified as a UNC name,");
+	printf(" to a local directory.\n\nOptions:\n");
+	printf("\tuser=<arg>\n\tpass=<arg>\n\tdom=<arg>\n");
+	printf("\nLess commonly used options:");
+	printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,rw,ro,");
+	printf("\n\tsep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,serverino,");
+	printf("\n\tmapchars,nomapchars,nolock,servernetbiosname=<SRV_RFC1001NAME>");
+	printf("\n\tdirectio,nounix,cifsacl,sec=<authentication mechanism>,sign");
+	printf("\n\nOptions not needed for servers supporting CIFS Unix extensions");
+	printf("\n\t(e.g. unneeded for mounts to most Samba versions):");
+	printf("\n\tuid=<uid>,gid=<gid>,dir_mode=<mode>,file_mode=<mode>,sfu");
+	printf("\n\nRarely used options:");
+	printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,");
+	printf("\n\tdev,nodev,nouser_xattr,netbiosname=<OUR_RFC1001NAME>,hard,soft,intr,");
+	printf("\n\tnointr,ignorecase,noposixpaths,noacl,prefixpath=<path>,nobrl");
+	printf("\n\tin6_addr");
+	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:");
+	printf("\n\t%s -V\n",thisprogram);
+
+	SAFE_FREE(mountpassword);
+}
+
+/* caller frees username if necessary */
+static char * getusername(void) {
+	char *username = NULL;
+	struct passwd *password = getpwuid(getuid());
+
+	if (password) {
+		username = password->pw_name;
+	}
+	return username;
+}
+
+static int open_cred_file(char * file_name)
+{
+	char * line_buf;
+	char * temp_val;
+	FILE * fs;
+	int i, length;
+	fs = fopen(file_name,"r");
+	if(fs == NULL)
+		return errno;
+	line_buf = (char *)malloc(4096);
+	if(line_buf == NULL) {
+		fclose(fs);
+		return ENOMEM;
+	}
+
+	while(fgets(line_buf,4096,fs)) {
+		/* parse line from credential file */
+
+		/* eat leading white space */
+		for(i=0;i<4086;i++) {
+			if((line_buf[i] != ' ') && (line_buf[i] != '\t'))
+				break;
+			/* if whitespace - skip past it */
+		}
+		if (strncasecmp("username",line_buf+i,8) == 0) {
+			temp_val = strchr(line_buf + i,'=');
+			if(temp_val) {
+				/* go past equals sign */
+				temp_val++;
+				for(length = 0;length<4087;length++) {
+					if ((temp_val[length] == '\n')
+					    || (temp_val[length] == '\0')) {
+						temp_val[length] = '\0';
+						break;
+					}
+				}
+				if(length > 4086) {
+					printf("mount.cifs failed due to malformed username in credentials file");
+					memset(line_buf,0,4096);
+					exit(EX_USAGE);
+				} else {
+					got_user = 1;
+					user_name = (char *)calloc(1 + length,1);
+					/* BB adding free of user_name string before exit,
+						not really necessary but would be cleaner */
+					strlcpy(user_name,temp_val, length+1);
+				}
+			}
+		} else if (strncasecmp("password",line_buf+i,8) == 0) {
+			temp_val = strchr(line_buf+i,'=');
+			if(temp_val) {
+				/* go past equals sign */
+				temp_val++;
+				for(length = 0;length<MOUNT_PASSWD_SIZE+1;length++) {
+					if ((temp_val[length] == '\n')
+					    || (temp_val[length] == '\0')) {
+						temp_val[length] = '\0';
+						break;
+					}
+				}
+				if(length > MOUNT_PASSWD_SIZE) {
+					printf("mount.cifs failed: password in credentials file too long\n");
+					memset(line_buf,0, 4096);
+					exit(EX_USAGE);
+				} else {
+					if(mountpassword == NULL) {
+						mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
+					} else
+						memset(mountpassword,0,MOUNT_PASSWD_SIZE);
+					if(mountpassword) {
+						strlcpy(mountpassword,temp_val,MOUNT_PASSWD_SIZE+1);
+						got_password = 1;
+					}
+				}
+			}
+                } else if (strncasecmp("domain",line_buf+i,6) == 0) {
+                        temp_val = strchr(line_buf+i,'=');
+                        if(temp_val) {
+                                /* go past equals sign */
+                                temp_val++;
+				if(verboseflag)
+					printf("\nDomain %s\n",temp_val);
+                                for(length = 0;length<DOMAIN_SIZE+1;length++) {
+					if ((temp_val[length] == '\n')
+					    || (temp_val[length] == '\0')) {
+						temp_val[length] = '\0';
+						break;
+					}
+                                }
+                                if(length > DOMAIN_SIZE) {
+                                        printf("mount.cifs failed: domain in credentials file too long\n");
+                                        exit(EX_USAGE);
+                                } else {
+                                        if(domain_name == NULL) {
+                                                domain_name = (char *)calloc(DOMAIN_SIZE+1,1);
+                                        } else
+                                                memset(domain_name,0,DOMAIN_SIZE);
+                                        if(domain_name) {
+                                                strlcpy(domain_name,temp_val,DOMAIN_SIZE+1);
+                                                got_domain = 1;
+                                        }
+                                }
+                        }
+                }
+
+	}
+	fclose(fs);
+	SAFE_FREE(line_buf);
+	return 0;
+}
+
+static int get_password_from_file(int file_descript, char * filename)
+{
+	int rc = 0;
+	int i;
+	char c;
+
+	if(mountpassword == NULL)
+		mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
+	else 
+		memset(mountpassword, 0, MOUNT_PASSWD_SIZE);
+
+	if (mountpassword == NULL) {
+		printf("malloc failed\n");
+		exit(EX_SYSERR);
+	}
+
+	if(filename != NULL) {
+		file_descript = open(filename, O_RDONLY);
+		if(file_descript < 0) {
+			printf("mount.cifs failed. %s attempting to open password file %s\n",
+				   strerror(errno),filename);
+			exit(EX_SYSERR);
+		}
+	}
+	/* else file already open and fd provided */
+
+	for(i=0;i<MOUNT_PASSWD_SIZE;i++) {
+		rc = read(file_descript,&c,1);
+		if(rc < 0) {
+			printf("mount.cifs failed. Error %s reading password file\n",strerror(errno));
+			if(filename != NULL)
+				close(file_descript);
+			exit(EX_SYSERR);
+		} else if(rc == 0) {
+			if(mountpassword[0] == 0) {
+				if(verboseflag)
+					printf("\nWarning: null password used since cifs password file empty");
+			}
+			break;
+		} else /* read valid character */ {
+			if((c == 0) || (c == '\n')) {
+				mountpassword[i] = '\0';
+				break;
+			} else 
+				mountpassword[i] = c;
+		}
+	}
+	if((i == MOUNT_PASSWD_SIZE) && (verboseflag)) {
+		printf("\nWarning: password longer than %d characters specified in cifs password file",
+			MOUNT_PASSWD_SIZE);
+	}
+	got_password = 1;
+	if(filename != NULL) {
+		close(file_descript);
+	}
+
+	return rc;
+}
+
+static int parse_options(char ** optionsp, int * filesys_flags)
+{
+	const char * data;
+	char * percent_char = NULL;
+	char * value = NULL;
+	char * next_keyword = NULL;
+	char * out = NULL;
+	int out_len = 0;
+	int word_len;
+	int rc = 0;
+	char user[32];
+	char group[32];
+
+	if (!optionsp || !*optionsp)
+		return 1;
+	data = *optionsp;
+
+	if(verboseflag)
+		printf("parsing options: %s\n", data);
+
+	/* BB fixme check for separator override BB */
+
+	if (getuid()) {
+		got_uid = 1;
+		snprintf(user,sizeof(user),"%u",getuid());
+		got_gid = 1;
+		snprintf(group,sizeof(group),"%u",getgid());
+	}
+
+/* while ((data = strsep(&options, ",")) != NULL) { */
+	while(data != NULL) {
+		/*  check if ends with trailing comma */
+		if(*data == 0)
+			break;
+
+		/* format is keyword=value,keyword2=value2,keyword3=value3 etc.) */
+		/* data  = next keyword */
+		/* value = next value ie stuff after equal sign */
+
+		next_keyword = strchr(data,','); /* BB handle sep= */
+	
+		/* temporarily null terminate end of keyword=value pair */
+		if(next_keyword)
+			*next_keyword++ = 0;
+
+		/* temporarily null terminate keyword to make keyword and value distinct */
+		if ((value = strchr(data, '=')) != NULL) {
+			*value = '\0';
+			value++;
+		}
+
+		if (strncmp(data, "users",5) == 0) {
+			if(!value || !*value) {
+				goto nocopy;
+			}
+		} 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)
+						printf("\nskipping empty user mount parameter\n");
+					/* remove the parm since it would otherwise be confusing
+					to the kernel code which would think it was a real username */
+					goto nocopy;
+				} else {
+					printf("username specified with no parameter\n");
+					SAFE_FREE(out);
+					return 1;	/* needs_arg; */
+				}
+			} else {
+				if (strnlen(value, 260) < 260) {
+					got_user=1;
+					percent_char = strchr(value,'%');
+					if(percent_char) {
+						*percent_char = ',';
+						if(mountpassword == NULL)
+							mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
+						if(mountpassword) {
+							if(got_password)
+								printf("\nmount.cifs warning - password specified twice\n");
+							got_password = 1;
+							percent_char++;
+							strlcpy(mountpassword, percent_char,MOUNT_PASSWD_SIZE+1);
+						/*  remove password from username */
+							while(*percent_char != 0) {
+								*percent_char = ',';
+								percent_char++;
+							}
+						}
+					}
+					/* 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");
+					SAFE_FREE(out);
+					return 1;
+				}
+			}
+		} else if (strncmp(data, "pass", 4) == 0) {
+			if (!value || !*value) {
+				if(got_password) {
+					printf("\npassword specified twice, ignoring second\n");
+				} else
+					got_password = 1;
+			} else if (strnlen(value, MOUNT_PASSWD_SIZE) < MOUNT_PASSWD_SIZE) {
+				if(got_password)
+					printf("\nmount.cifs warning - password specified twice\n");
+				got_password = 1;
+			} else {
+				printf("password too long\n");
+				SAFE_FREE(out);
+				return 1;
+			}
+		} else if (strncmp(data, "sec", 3) == 0) {
+			if (value) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list