smbw.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,563 行 · 第 1/3 页
C
1,563 行
/* Unix SMB/CIFS implementation. SMB wrapper functions 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"#include "realcalls.h"pstring smbw_cwd;static struct smbw_file *smbw_files;static struct smbw_server *smbw_srvs;struct bitmap *smbw_file_bmap;fstring smbw_prefix = SMBW_PREFIX;int smbw_busy=0;/* needs to be here because of dumb include files on some systems */int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;/***************************************************** initialise structures*******************************************************/void smbw_init(void){ extern BOOL in_client; static int initialised; char *p; int eno; pstring line; if (initialised) return; initialised = 1; eno = errno; smbw_busy++; DEBUGLEVEL = 0; setup_logging("smbsh",True); dbf = x_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); } in_client = True; load_interfaces(); if ((p=smbw_getshared("SERVICESF"))) { pstrcpy(dyn_CONFIGFILE, p); } lp_load(dyn_CONFIGFILE,True,False,False); if (!init_names()) exit(1); 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;}/***************************************************** determine if a file descriptor is a smb one*******************************************************/int smbw_fd(int fd){ if (smbw_busy) return 0; return smbw_file_bmap && bitmap_query(smbw_file_bmap, fd);}/***************************************************** determine if a file descriptor is an internal smbw fd*******************************************************/int smbw_local_fd(int fd){ struct smbw_server *srv; smbw_init(); if (smbw_busy) return 0; if (smbw_shared_fd(fd)) return 1; for (srv=smbw_srvs;srv;srv=srv->next) { if (srv->cli.fd == fd) return 1; } return 0;}/***************************************************** a crude inode number generator*******************************************************/ino_t smbw_inode(const char *name){ if (!*name) return 2; return (ino_t)str_checksum(name);}/***************************************************** remove redundent stuff from a filename*******************************************************/void clean_fname(char *name){ char *p, *p2; int l; int modified = 1; if (!name) return; while (modified) { modified = 0; DEBUG(5,("cleaning %s\n", name)); if ((p=strstr(name,"/./"))) { modified = 1; while (*p) { p[0] = p[2]; p++; } } if ((p=strstr(name,"//"))) { modified = 1; while (*p) { p[0] = p[1]; p++; } } if (strcmp(name,"/../")==0) { modified = 1; name[1] = 0; } if ((p=strstr(name,"/../"))) { modified = 1; for (p2=(p>name?p-1:p);p2>name;p2--) { if (p2[0] == '/') break; } while (*p2) { p2[0] = p2[3]; p2++; } } if (strcmp(name,"/..")==0) { modified = 1; name[1] = 0; } l = strlen(name); p = l>=3?(name+l-3):name; if (strcmp(p,"/..")==0) { modified = 1; for (p2=p-1;p2>name;p2--) { if (p2[0] == '/') break; } if (p2==name) { p[0] = '/'; p[1] = 0; } else { p2[0] = 0; } } l = strlen(name); p = l>=2?(name+l-2):name; if (strcmp(p,"/.")==0) { if (p == name) { p[1] = 0; } else { p[0] = 0; } } if (strncmp(p=name,"./",2) == 0) { modified = 1; do { p[0] = p[2]; } while (*p++); } l = strlen(p=name); if (l > 1 && p[l-1] == '/') { modified = 1; p[l-1] = 0; } }}/***************************************************** 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;}/***************************************************** parse a smb path into its components. server is one of 1) the name of the SMB server 2) WORKGROUP#1D for share listing 3) WORKGROUP#__ for workgroup listingshare is the share on the server to querypath is the SMB path on the serverreturn the full path (ie. add cwd if needed)*******************************************************/char *smbw_parse_path(const char *fname, char *server, char *share, char *path){ static pstring s; char *p; int len; fstring workgroup; /* add cwd if necessary */ if (fname[0] != '/') { slprintf(s, sizeof(s), "%s/%s", smbw_cwd, fname); } else { pstrcpy(s, fname); } clean_fname(s); /* see if it has the right prefix */ len = strlen(smbw_prefix)-1; if (strncmp(s,smbw_prefix,len) || (s[len] != '/' && s[len] != 0)) return s; /* ok, its for us. Now parse out the workgroup, share etc. */ p = s+len; if (*p == '/') p++; if (!next_token(&p, workgroup, "/", sizeof(fstring))) { /* we're in /smb - give a list of workgroups */ slprintf(server,sizeof(fstring), "%s#01", smbw_find_workgroup()); fstrcpy(share,"IPC$"); pstrcpy(path,""); return s; } if (!next_token(&p, server, "/", sizeof(fstring))) { /* we are in /smb/WORKGROUP */ slprintf(server,sizeof(fstring), "%s#1D", workgroup); fstrcpy(share,"IPC$"); pstrcpy(path,""); } if (!next_token(&p, share, "/", sizeof(fstring))) { /* we are in /smb/WORKGROUP/SERVER */ fstrcpy(share,"IPC$"); pstrcpy(path,""); } pstrcpy(path, p); all_string_sub(path, "/", "\\", 0); return s;}/***************************************************** determine if a path name (possibly relative) is in the smb name space*******************************************************/int smbw_path(const char *path){ fstring server, share; pstring s; char *cwd; int len; if(!path) return 0; /* this is needed to prevent recursion with the BSD malloc which opens /etc/malloc.conf on the first call */ if (strncmp(path,"/etc/", 5) == 0) { return 0; } smbw_init(); len = strlen(smbw_prefix)-1; if (path[0] == '/' && strncmp(path,smbw_prefix,len)) { return 0; } if (smbw_busy) return 0; DEBUG(3,("smbw_path(%s)\n", path)); cwd = smbw_parse_path(path, server, share, s); if (strncmp(cwd,smbw_prefix,len) == 0 && (cwd[len] == '/' || cwd[len] == 0)) { return 1; } return 0;}/***************************************************** return a unix errno from a SMB error pair*******************************************************/int smbw_errno(struct cli_state *c){ return cli_errno(c);}/* Return a username and password given a server and share name */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 = "guest"; *workgroup = smbw_getshared("WORKGROUP"); if (!*workgroup) *workgroup = lp_workgroup(); *password = smbw_getshared("PASSWORD"); if (!*password) *password = "";}static smbw_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data;/*****************************************************set the get auth data function******************************************************/void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn){ get_auth_data_fn = fn;}/***************************************************** 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_m(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { struct in_addr sip; pstring s; fstrcpy(group, server_n); p = strchr_m(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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?