void get_envvar_auth_data(char *server, char *share, char **workgroup, char **username, char **password) { /* Fall back to shared memory/environment variables */ *username = smbw_getshared("USER"); if (!*username) *username = getenv("USER"); if (!*username) *username = "******"; *workgroup = smbw_getshared("WORKGROUP"); if (!*workgroup) *workgroup = lp_workgroup(); *password = smbw_getshared("PASSWORD"); if (!*password) *password = ""; }
/***************************************************** set a variable in the shared area *******************************************************/ void smbw_setshared(const char *name, const char *val) { int l1, l2; /* we don't allow variable overwrite */ if (smbw_getshared(name)) return; lockit(); l1 = strlen(name)+1; l2 = strlen(val)+1; variables = (char *)Realloc(variables, shared_size + l1+l2+4); if (!variables) { DEBUG(0,("out of memory in smbw_setshared\n")); exit(1); } SSVAL(&variables[shared_size], 0, l1); SSVAL(&variables[shared_size], 2, l2); pstrcpy(&variables[shared_size] + 4, name); pstrcpy(&variables[shared_size] + 4 + l1, val); shared_size += l1+l2+4; 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(); }
/***************************************************** find a workgroup (any workgroup!) that has a master browser on the local network *******************************************************/ static char *smbw_find_workgroup(void) { fstring server; char *p; struct in_addr *ip_list = NULL; int count = 0; int i; /* first off see if an existing workgroup name exists */ p = smbw_getshared("WORKGROUP"); if (!p) p = lp_workgroup(); slprintf(server, sizeof(server), "%s#1D", p); if (smbw_server(server, "IPC$")) return p; /* go looking for workgroups */ if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { DEBUG(1,("No workgroups found!")); return p; } for (i=0;i<count;i++) { static fstring name; if (name_status_find("*", 0, 0x1d, ip_list[i], name)) { slprintf(server, sizeof(server), "%s#1D", name); if (smbw_server(server, "IPC$")) { smbw_setshared("WORKGROUP", name); SAFE_FREE(ip_list); return name; } } } SAFE_FREE(ip_list); return p; }
int main(int argc, char *argv[]) { char *p, *u; const char *libd = dyn_LIBDIR; pstring line, wd; int opt; extern char *optarg; extern int optind; dbf = x_stdout; smbw_setup_shared(); while ((opt = getopt(argc, argv, "W:U:R:d:P:l:hL:")) != EOF) { switch (opt) { case 'L': libd = optarg; break; case 'W': smbw_setshared("WORKGROUP", optarg); break; case 'l': smbw_setshared("LOGFILE", optarg); break; case 'P': smbw_setshared("PREFIX", optarg); break; case 'd': smbw_setshared("DEBUG", optarg); break; case 'U': p = strchr_m(optarg,'%'); if (p) { *p=0; smbw_setshared("PASSWORD",p+1); } smbw_setshared("USER", optarg); break; case 'R': smbw_setshared("RESOLVE_ORDER",optarg); break; case 'h': default: smbsh_usage(); } } if (!smbw_getshared("USER")) { printf("Username: "******"USER", u); } if (!smbw_getshared("PASSWORD")) { p = getpass("Password: "******"PASSWORD", p); } setenv("PS1", "smbsh$ ", 1); sys_getwd(wd); slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid()); smbw_setshared(line, wd); slprintf(line,sizeof(line)-1,"%s/smbwrapper.so", libd); setenv("LD_PRELOAD", line, 1); slprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so", libd); if (file_exist(line, NULL)) { slprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so:DEFAULT", libd); setenv("_RLD_LIST", line, 1); slprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd); setenv("_RLDN32_LIST", line, 1); } else { slprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd); setenv("_RLD_LIST", line, 1); } { char *shellpath = getenv("SHELL"); if(shellpath) execl(shellpath,"smbsh",NULL); else execl("/bin/sh","smbsh",NULL); } printf("launch failed!\n"); return 1; }
/***************************************************** initialise structures *******************************************************/ void smbw_init(void) { extern BOOL in_client; static int initialised; static pstring servicesf = CONFIGFILE; extern FILE *dbf; char *p; int eno; pstring line; if (initialised) return; initialised = 1; eno = errno; smbw_busy++; DEBUGLEVEL = 0; AllowDebugChange = False; setup_logging("smbsh",True); dbf = stderr; if ((p=smbw_getshared("LOGFILE"))) { dbf = sys_fopen(p, "a"); } smbw_file_bmap = bitmap_allocate(SMBW_MAX_OPEN); if (!smbw_file_bmap) { exit(1); } charset_initialise(); in_client = True; load_interfaces(); if ((p=smbw_getshared("SERVICESF"))) { pstrcpy(servicesf, p); } lp_load(servicesf,True,False,False); codepage_initialise(lp_client_code_page()); get_myname(global_myname); if ((p=smbw_getshared("DEBUG"))) { DEBUGLEVEL = atoi(p); } if ((p=smbw_getshared("RESOLVE_ORDER"))) { lp_set_name_resolve_order(p); } if ((p=smbw_getshared("PREFIX"))) { slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p); all_string_sub(smbw_prefix,"//", "/", 0); DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix)); } slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid()); p = smbw_getshared(line); if (!p) { sys_getwd(smbw_cwd); } pstrcpy(smbw_cwd, p); DEBUG(4,("Initial cwd is %s\n", smbw_cwd)); smbw_busy--; set_maxfiles(SMBW_MAX_OPEN); BlockSignals(True,SIGPIPE); errno = eno; }
/***************************************************** return a connection to a server (existing or new) *******************************************************/ struct smbw_server *smbw_server(char *server, char *share) { struct smbw_server *srv=NULL; struct cli_state c; char *username; char *password; char *workgroup; struct nmb_name called, calling; char *p, *server_n = server; fstring group; pstring ipenv; struct in_addr ip; zero_ip(&ip); ZERO_STRUCT(c); get_auth_data_fn(server, share, &workgroup, &username, &password); /* try to use an existing connection */ for (srv=smbw_srvs;srv;srv=srv->next) { if (strcmp(server,srv->server_name)==0 && strcmp(share,srv->share_name)==0 && strcmp(workgroup,srv->workgroup)==0 && strcmp(username, srv->username) == 0) return srv; } if (server[0] == 0) { errno = EPERM; return NULL; } make_nmb_name(&calling, global_myname, 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server)); if ((p=strchr(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { struct in_addr sip; pstring s; fstrcpy(group, server_n); p = strchr(group,'#'); *p = 0; /* cache the workgroup master lookup */ slprintf(s,sizeof(s)-1,"MASTER_%s", group); if (!(server_n = smbw_getshared(s))) { if (!find_master_ip(group, &sip)) { errno = ENOENT; return NULL; } fstrcpy(group, inet_ntoa(sip)); server_n = group; smbw_setshared(s,server_n); } } DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); zero_ip(&ip); if ((p=smbw_getshared(ipenv))) { ip = *(interpret_addr2(p)); } /* have to open a new connection */ if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { errno = ENOENT; return NULL; } if (!cli_session_request(&c, &calling, &called)) { cli_shutdown(&c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } errno = ENOENT; return NULL; } DEBUG(4,(" session request ok\n")); if (!cli_negprot(&c)) { cli_shutdown(&c); errno = ENOENT; return NULL; } if (!cli_session_setup(&c, username, password, strlen(password), password, strlen(password), workgroup) && /* try an anonymous login if it failed */ !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) { cli_shutdown(&c); errno = EPERM; return NULL; } DEBUG(4,(" session setup ok\n")); if (!cli_send_tconX(&c, share, "?????", password, strlen(password)+1)) { errno = smbw_errno(&c); cli_shutdown(&c); return NULL; } smbw_setshared(ipenv,inet_ntoa(ip)); DEBUG(4,(" tconx ok\n")); srv = (struct smbw_server *)malloc(sizeof(*srv)); if (!srv) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(srv); srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->server_name = strdup(server); if (!srv->server_name) { errno = ENOMEM; goto failed; } srv->share_name = strdup(share); if (!srv->share_name) { errno = ENOMEM; goto failed; } srv->workgroup = strdup(workgroup); if (!srv->workgroup) { errno = ENOMEM; goto failed; } srv->username = strdup(username); if (!srv->username) { errno = ENOMEM; goto failed; } /* some programs play with file descriptors fairly intimately. We try to get out of the way by duping to a high fd number */ if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) { if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) == srv->cli.fd+SMBW_CLI_FD) { close(srv->cli.fd); srv->cli.fd += SMBW_CLI_FD; } } DLIST_ADD(smbw_srvs, srv); return srv; failed: cli_shutdown(&c); if (!srv) return NULL; SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv); return NULL; }