diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/filename.c | 14 | ||||
-rw-r--r-- | source3/smbd/service.c | 180 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 6 | ||||
-rw-r--r-- | source3/smbd/vfs.c | 13 |
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 = ¶ms[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 } - |