summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/filename.c14
-rw-r--r--source3/smbd/service.c180
-rw-r--r--source3/smbd/trans2.c6
-rw-r--r--source3/smbd/vfs.c13
4 files changed, 105 insertions, 108 deletions
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 8300674d61..805af9c494 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
filename handling routines
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Jeremy Allison 1999-200
+ Copyright (C) Jeremy Allison 1999-2004
Copyright (C) Ying Chen 2000
This program is free software; you can redistribute it and/or modify
@@ -392,9 +392,10 @@ BOOL check_name(pstring name,connection_struct *conn)
errno = 0;
if (IS_VETO_PATH(conn, name)) {
- if(strcmp(name, ".") && strcmp(name, "..")) {
+ /* Is it not dot or dot dot. */
+ if (!((name[0] == '.') && (!name[1] || (name[1] == '.' && !name[2])))) {
DEBUG(5,("file path name %s vetoed\n",name));
- return(0);
+ return False;
}
}
@@ -412,7 +413,7 @@ BOOL check_name(pstring name,connection_struct *conn)
if ( (SMB_VFS_LSTAT(conn,name,&statbuf) != -1) &&
(S_ISLNK(statbuf.st_mode)) ) {
DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
- ret=0;
+ ret = False;
}
}
#endif
@@ -464,8 +465,11 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength,
/* now scan for matching names */
while ((dname = ReadDirName(cur_dir))) {
- if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
+
+ /* Is it dot or dot dot. */
+ if ((dname[0] == '.') && (!dname[1] || (dname[1] == '.' && !dname[2]))) {
continue;
+ }
/*
* At this point dname is the unmangled name.
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 78b610ae37..a53b9267b7 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -112,105 +112,96 @@ int add_home_service(const char *service, const char *username, const char *home
/**
- * Find a service entry. service is always in dos codepage.
+ * Find a service entry.
*
* @param service is modified (to canonical form??)
**/
+
int find_service(fstring service)
{
- int iService;
-
- all_string_sub(service,"\\","/",0);
-
- iService = lp_servicenumber(service);
-
- /* now handle the special case of a home directory */
- if (iService < 0)
- {
- char *phome_dir = get_user_home_dir(service);
-
- if(!phome_dir)
- {
- /*
- * Try mapping the servicename, it may
- * be a Windows to unix mapped user name.
- */
- if(map_username(service))
- phome_dir = get_user_home_dir(service);
- }
-
- DEBUG(3,("checking for home directory %s gave %s\n",service,
- phome_dir?phome_dir:"(NULL)"));
-
- iService = add_home_service(service,service /* 'username' */, phome_dir);
- }
-
- /* If we still don't have a service, attempt to add it as a printer. */
- if (iService < 0)
- {
- int iPrinterService;
-
- if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
- {
- char *pszTemp;
-
- DEBUG(3,("checking whether %s is a valid printer name...\n", service));
- pszTemp = lp_printcapname();
- if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
- {
- DEBUG(3,("%s is a valid printer name\n", service));
- DEBUG(3,("adding %s as a printer service\n", service));
- lp_add_printer(service, iPrinterService);
- iService = lp_servicenumber(service);
- if (iService < 0)
- DEBUG(0,("failed to add %s as a printer service!\n", service));
- }
- else
- DEBUG(3,("%s is not a valid printer name\n", service));
- }
- }
-
- /* Check for default vfs service? Unsure whether to implement this */
- if (iService < 0)
- {
- }
-
- /* just possibly it's a default service? */
- if (iService < 0)
- {
- char *pdefservice = lp_defaultservice();
- if (pdefservice && *pdefservice &&
- !strequal(pdefservice,service) &&
- !strstr(service,".."))
- {
- /*
- * We need to do a local copy here as lp_defaultservice()
- * returns one of the rotating lp_string buffers that
- * could get overwritten by the recursive find_service() call
- * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
- */
- pstring defservice;
- pstrcpy(defservice, pdefservice);
- iService = find_service(defservice);
- if (iService >= 0)
- {
- all_string_sub(service, "_","/",0);
- iService = lp_add_service(service, iService);
- }
- }
- }
-
- if (iService >= 0)
- if (!VALID_SNUM(iService))
- {
- DEBUG(0,("Invalid snum %d for %s\n",iService, service));
- iService = -1;
- }
-
- if (iService < 0)
- DEBUG(3,("find_service() failed to find service %s\n", service));
-
- return (iService);
+ int iService;
+
+ all_string_sub(service,"\\","/",0);
+
+ iService = lp_servicenumber(service);
+
+ /* now handle the special case of a home directory */
+ if (iService < 0) {
+ char *phome_dir = get_user_home_dir(service);
+
+ if(!phome_dir) {
+ /*
+ * Try mapping the servicename, it may
+ * be a Windows to unix mapped user name.
+ */
+ if(map_username(service))
+ phome_dir = get_user_home_dir(service);
+ }
+
+ DEBUG(3,("checking for home directory %s gave %s\n",service,
+ phome_dir?phome_dir:"(NULL)"));
+
+ iService = add_home_service(service,service /* 'username' */, phome_dir);
+ }
+
+ /* If we still don't have a service, attempt to add it as a printer. */
+ if (iService < 0) {
+ int iPrinterService;
+
+ if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
+ char *pszTemp;
+
+ DEBUG(3,("checking whether %s is a valid printer name...\n", service));
+ pszTemp = lp_printcapname();
+ if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) {
+ DEBUG(3,("%s is a valid printer name\n", service));
+ DEBUG(3,("adding %s as a printer service\n", service));
+ lp_add_printer(service, iPrinterService);
+ iService = lp_servicenumber(service);
+ if (iService < 0) {
+ DEBUG(0,("failed to add %s as a printer service!\n", service));
+ }
+ } else {
+ DEBUG(3,("%s is not a valid printer name\n", service));
+ }
+ }
+ }
+
+ /* Check for default vfs service? Unsure whether to implement this */
+ if (iService < 0) {
+ }
+
+ /* just possibly it's a default service? */
+ if (iService < 0) {
+ char *pdefservice = lp_defaultservice();
+ if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr(service,"..")) {
+ /*
+ * We need to do a local copy here as lp_defaultservice()
+ * returns one of the rotating lp_string buffers that
+ * could get overwritten by the recursive find_service() call
+ * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
+ */
+ pstring defservice;
+ pstrcpy(defservice, pdefservice);
+ iService = find_service(defservice);
+ if (iService >= 0) {
+ all_string_sub(service, "_","/",0);
+ iService = lp_add_service(service, iService);
+ }
+ }
+ }
+
+ if (iService >= 0) {
+ if (!VALID_SNUM(iService)) {
+ DEBUG(0,("Invalid snum %d for %s\n",iService, service));
+ iService = -1;
+ }
+ }
+
+ if (iService < 0)
+ DEBUG(3,("find_service() failed to find service %s\n", service));
+
+ return (iService);
}
@@ -218,6 +209,7 @@ int find_service(fstring service)
do some basic sainity checks on the share.
This function modifies dev, ecode.
****************************************************************************/
+
static NTSTATUS share_sanity_checks(int snum, fstring dev)
{
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index e2df517f40..38fed4beae 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -249,6 +249,9 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
open_size = IVAL(params,14);
pname = &params[28];
+ if (IS_IPC(conn))
+ return(ERROR_DOS(ERRSRV,ERRaccess));
+
srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
@@ -257,9 +260,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
fname,open_mode, open_attr, open_ofun, open_size));
- if (IS_IPC(conn))
- return(ERROR_DOS(ERRSRV,ERRaccess));
-
/* XXXX we need to handle passed times, sattr and flags */
unix_convert(fname,conn,0,&bad_path,&sbuf);
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 284e24e7b1..4f3234775a 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -863,8 +863,8 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir)
DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
- /* remove any double slashes */
- all_string_sub(s,"//","/",0);
+ /* We know there are no double slashes as this comes from srvstr_get_path().
+ and has gone through check_path_syntax(). JRA */
pstrcpy(base_name,s);
p = strrchr_m(base_name,'/');
@@ -915,17 +915,19 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir)
{
size_t l = strlen(dir2);
- if (dir2[l-1] == '/')
+ char *last_slash = strrchr_m(dir2, '/');
+
+ if (last_slash && (last_slash[1] == '\0'))
l--;
if (strncmp(newname,dir2,l) != 0) {
vfs_ChDir(conn,wd);
- DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l));
+ DEBUG(2,("Bad access attempt: s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l));
return(False);
}
if (!readlink_check(conn, dir, newname)) {
- DEBUG(2, ("Bad access attemt? %s is a symlink outside the share path", s));
+ DEBUG(2, ("Bad access attemt: %s is a symlink outside the share path", s));
return(False);
}
@@ -947,4 +949,3 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir)
return(True);
#endif
}
-