diff options
-rw-r--r-- | source3/smbwrapper/shared.c | 179 | ||||
-rw-r--r-- | source3/smbwrapper/smbsh.c | 34 | ||||
-rw-r--r-- | source3/smbwrapper/smbw.c | 51 | ||||
-rw-r--r-- | source3/smbwrapper/smbw.h | 1 |
4 files changed, 242 insertions, 23 deletions
diff --git a/source3/smbwrapper/shared.c b/source3/smbwrapper/shared.c new file mode 100644 index 0000000000..4637248dce --- /dev/null +++ b/source3/smbwrapper/shared.c @@ -0,0 +1,179 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions - shared variables + Copyright (C) Andrew Tridgell 1998 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + +static int shared_fd; +static char *variables; +static int shared_size; + +/***************************************************** +setup the shared area +*******************************************************/ +void smbw_setup_shared(void) +{ + int fd; + pstring s, name; + + slprintf(s,sizeof(s)-1, "%s/msg.XXXXXX",tmpdir()); + + fstrcpy(name,(char *)mktemp(s)); + + /* note zero permissions! don't change this */ + fd = open(name,O_RDWR|O_CREAT|O_TRUNC|O_EXCL,0); + if (fd == -1) goto failed; + + shared_fd = set_maxfiles(SMBW_MAX_OPEN); + + while (shared_fd && dup2(fd, shared_fd) != shared_fd) shared_fd--; + + if (shared_fd == 0) goto failed; + + close(fd); + + DEBUG(4,("created shared_fd=%d\n", shared_fd)); + + slprintf(s,sizeof(s)-1,"%d", shared_fd); + + setenv("SMBW_HANDLE", s, 1); + + return; + + failed: + perror("Failed to setup shared variable area "); + exit(1); +} + + +/***************************************************** +lock the shared variable area +*******************************************************/ +static void lockit(void) +{ + if (shared_fd == 0) { + char *p = getenv("SMBW_HANDLE"); + if (!p) { + DEBUG(0,("ERROR: can't get smbw shared handle\n")); + exit(1); + } + shared_fd = atoi(p); + } + if (fcntl_lock(shared_fd,SMB_F_SETLKW,0,1,F_WRLCK)==False) { + DEBUG(0,("ERROR: can't get smbw shared lock\n")); + exit(1); + } +} + +/***************************************************** +unlock the shared variable area +*******************************************************/ +static void unlockit(void) +{ + fcntl_lock(shared_fd,SMB_F_SETLK,0,1,F_UNLCK); +} + + +/***************************************************** +get a variable from the shared area +*******************************************************/ +char *smbw_getshared(const char *name) +{ + int i; + struct stat st; + + lockit(); + + /* maybe the area has changed */ + if (fstat(shared_fd, &st)) goto failed; + + if (st.st_size != shared_size) { + variables = (char *)Realloc(variables, st.st_size); + if (!variables) goto failed; + shared_size = st.st_size; + lseek(shared_fd, 0, SEEK_SET); + if (read(shared_fd, variables, shared_size) != shared_size) { + goto failed; + } + } + + unlockit(); + + i=0; + while (i < shared_size) { + int len; + char *n, *v; + + n = &variables[i]; + i += strlen(n)+1; + v = &variables[i]; + i += strlen(v)+1; + + if (strcmp(name,n)) { + continue; + } + return v; + } + + return NULL; + + failed: + DEBUG(0,("smbw: shared variables corrupt (%s)\n", strerror(errno))); + exit(1); +} + + + +/***************************************************** +set a variable in the shared area +*******************************************************/ +void smbw_setshared(const char *name, const char *val) +{ + int len; + + /* we don't allow variable overwrite */ + if (smbw_getshared(name)) return; + + lockit(); + + len = strlen(name) + strlen(val) + 2; + + variables = (char *)Realloc(variables, shared_size + len); + + if (!variables) { + DEBUG(0,("out of memory in smbw_setshared\n")); + exit(1); + } + + pstrcpy(&variables[shared_size], name); + shared_size += strlen(name)+1; + pstrcpy(&variables[shared_size], val); + shared_size += strlen(val)+1; + + lseek(shared_fd, 0, SEEK_SET); + if (write(shared_fd, variables, shared_size) != shared_size) { + DEBUG(0,("smbw_setshared failed (%s)\n", strerror(errno))); + exit(1); + } + + unlockit(); +} diff --git a/source3/smbwrapper/smbsh.c b/source3/smbwrapper/smbsh.c index 28bdaad7e3..0489bb2b63 100644 --- a/source3/smbwrapper/smbsh.c +++ b/source3/smbwrapper/smbsh.c @@ -24,17 +24,37 @@ int main(int argc, char *argv[]) { char *p, *u; - char *libd = BINDIR; - + char *libd = BINDIR; pstring line; + extern FILE *dbf; - printf("Username: "); - u = fgets_slash(line, sizeof(line)-1, stdin); + smbw_setup_shared(); - p = getpass("Password: "); + p = getenv("SMBW_DEBUG"); + if (p) smbw_setshared("DEBUG", p); + + p = getenv("SMBW_WORKGROUP"); + if (p) smbw_setshared("WORKGROUP", p); + + p = getenv("SMBW_USER"); + if (p) smbw_setshared("USER", p); + + p = getenv("SMBW_PASSWORD"); + if (p) smbw_setshared("PASSWORD", p); + + charset_initialise(); + + if (!smbw_getshared("USER")) { + printf("Username: "); + u = fgets_slash(line, sizeof(line)-1, stdin); + smbw_setshared("USER", u); + } + + if (!smbw_getshared("PASSWORD")) { + p = getpass("Password: "); + smbw_setshared("PASSWORD", p); + } - setenv("SMBW_USER", u, 1); - setenv("SMBW_PASSWORD", p, 1); setenv("PS1", "smbsh$ ", 1); sys_getwd(line); diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c index 0d713da797..7ddc46ca9b 100644 --- a/source3/smbwrapper/smbw.c +++ b/source3/smbwrapper/smbw.c @@ -58,11 +58,11 @@ void smbw_init(void) smbw_busy++; DEBUGLEVEL = 0; - setup_logging("smbw",True); + setup_logging("smbsh",True); dbf = stderr; - if ((p=getenv("SMBW_LOGFILE"))) { + if ((p=smbw_getshared("LOGFILE"))) { dbf = fopen(p, "a"); } @@ -81,11 +81,11 @@ void smbw_init(void) get_myname(global_myname,NULL); - if ((p=getenv("SMBW_DEBUG"))) { + if ((p=smbw_getshared("DEBUG"))) { DEBUGLEVEL = atoi(p); } - if ((p=getenv("SMBW_PREFIX"))) { + if ((p=smbw_getshared("PREFIX"))) { slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p); string_sub(smbw_prefix,"//", "/"); DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix)); @@ -100,7 +100,7 @@ void smbw_init(void) } smbw_busy--; - set_maxfiles(lp_max_open_files()+10); + set_maxfiles(SMBW_MAX_OPEN); errno = eno; } @@ -259,7 +259,7 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path) p = p2; if (!p) { if (len == 0) { - char *workgroup = getenv("SMBW_WORKGROUP"); + char *workgroup = smbw_getshared("WORKGROUP"); if (!workgroup) workgroup = lp_workgroup(); slprintf(server,sizeof(fstring)-1, "%s#1D", workgroup); } @@ -364,17 +364,21 @@ struct smbw_server *smbw_server(char *server, char *share) struct nmb_name called, calling; char *p, *server_n = server; fstring group; + pstring ipenv; + struct in_addr ip; + extern struct in_addr ipzero; + ip = ipzero; ZERO_STRUCT(c); - username = getenv("SMBW_USER"); + username = smbw_getshared("USER"); if (!username) username = getenv("USER"); if (!username) username = "guest"; - workgroup = getenv("SMBW_WORKGROUP"); + workgroup = smbw_getshared("WORKGROUP"); if (!workgroup) workgroup = lp_workgroup(); - password = getenv("SMBW_PASSWORD"); + password = smbw_getshared("PASSWORD"); if (!password) password = ""; /* try to use an existing connection */ @@ -395,22 +399,37 @@ struct smbw_server *smbw_server(char *server, char *share) if ((p=strchr(server_n,'#')) && strcmp(p+1,"1D")==0) { struct in_addr ip; + pstring s; + fstrcpy(group, server_n); p = strchr(group,'#'); *p = 0; - if (!find_master_ip(group, &ip)) { - errno = ENOENT; - return NULL; + + /* cache the workgroup master lookup */ + slprintf(s,sizeof(s)-1,"MASTER_%s", group); + if (!(server_n = smbw_getshared(s))) { + if (!find_master_ip(group, &ip)) { + errno = ENOENT; + return NULL; + } + fstrcpy(group, inet_ntoa(ip)); + server_n = group; + smbw_setshared(s,server_n); } - fstrcpy(group, inet_ntoa(ip)); - server_n = group; } DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: + slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); + + ip = ipzero; + if ((p=smbw_getshared(ipenv))) { + ip = *(interpret_addr2(p)); + } + /* have to open a new connection */ - if (!cli_initialise(&c) || !cli_connect(&c, server_n, NULL)) { + if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { errno = ENOENT; return NULL; } @@ -453,6 +472,8 @@ struct smbw_server *smbw_server(char *server, char *share) return NULL; } + smbw_setshared(ipenv,inet_ntoa(ip)); + DEBUG(4,(" tconx ok\n")); srv = (struct smbw_server *)malloc(sizeof(*srv)); diff --git a/source3/smbwrapper/smbw.h b/source3/smbwrapper/smbw.h index b0cf2dc2e1..8de5b5776a 100644 --- a/source3/smbwrapper/smbw.h +++ b/source3/smbwrapper/smbw.h @@ -30,7 +30,6 @@ #define SMBW_PWD_ENV "PWD" - struct smbw_server { struct smbw_server *next, *prev; struct cli_state cli; |