⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libsmbclient.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* Still used */			DEBUG(3, ("smbc_remove_usused_server: "                                  "%p still used by %p.\n", 				  srv, file));			return 1;		}	}	DLIST_REMOVE(context->internal->_servers, srv);	cli_shutdown(&srv->cli);	DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));	context->callbacks.remove_cached_srv_fn(context, srv);        SAFE_FREE(srv);		return 0;}static SMBCSRV *find_server(SMBCCTX *context,            const char *server,            const char *share,            fstring workgroup,            fstring username,            fstring password){        SMBCSRV *srv;        int auth_called = 0;         check_server_cache:	srv = context->callbacks.get_cached_srv_fn(context, server, share, 						   workgroup, username);	if (!auth_called && !srv && (!username[0] || !password[0])) {		context->callbacks.auth_fn(server, share,                                           workgroup, sizeof(fstring),                                           username, sizeof(fstring),                                           password, sizeof(fstring));		/*                 * However, smbc_auth_fn may have picked up info relating to                 * an existing connection, so try for an existing connection                 * again ...                 */		auth_called = 1;		goto check_server_cache;			}		if (srv) {		if (context->callbacks.check_server_fn(context, srv)) {			/*                         * This server is no good anymore                          * Try to remove it and check for more possible                         * servers in the cache                         */			if (context->callbacks.remove_unused_server_fn(context,                                                                       srv)) {                                 /*                                 * We could not remove the server completely,                                 * remove it from the cache so we will not get                                 * it again. It will be removed when the last                                 * file/dir is closed.                                 */				context->callbacks.remove_cached_srv_fn(context,                                                                        srv);			}						/*                         * Maybe there are more cached connections to this                         * server                         */			goto check_server_cache; 		}		return srv; 	}        return NULL;}/* * Connect to a server, possibly on an existing connection * * Here, what we want to do is: If the server and username * match an existing connection, reuse that, otherwise, establish a  * new connection. * * If we have to create a new connection, call the auth_fn to get the * info we need, unless the username and password were passed in. */static SMBCSRV *smbc_server(SMBCCTX *context,            BOOL connect_if_not_found,            const char *server,            const char *share,             fstring workgroup,            fstring username,             fstring password){	SMBCSRV *srv=NULL;	struct cli_state c;	struct nmb_name called, calling;	const char *server_n = server;	pstring ipenv;	struct in_addr ip;	int tried_reverse = 0;        int port_try_first;        int port_try_next;        const char *username_used;  	zero_ip(&ip);	ZERO_STRUCT(c);	if (server[0] == 0) {		errno = EPERM;		return NULL;	}        /* Look for a cached connection */        srv = find_server(context, server, share,                          workgroup, username, password);                /*         * If we found a connection and we're only allowed one share per         * server...         */        if (srv && *share != '\0' && context->options.one_share_per_server) {                /*                 * ... then if there's no current connection to the share,                 * connect to it.  find_server(), or rather the function                 * pointed to by context->callbacks.get_cached_srv_fn which                 * was called by find_server(), will have issued a tree                 * disconnect if the requested share is not the same as the                 * one that was already connected.                 */                if (srv->cli.cnum == (uint16) -1) {                        /* Ensure we have accurate auth info */                        context->callbacks.auth_fn(server, share,                                                   workgroup, sizeof(fstring),                                                   username, sizeof(fstring),                                                   password, sizeof(fstring));                        if (! cli_send_tconX(&srv->cli, share, "?????",                                             password, strlen(password)+1)) {                                                        errno = smbc_errno(context, &srv->cli);                                cli_shutdown(&srv->cli);                                context->callbacks.remove_cached_srv_fn(context,                                                                        srv);                                srv = NULL;                        }                        /*                         * Regenerate the dev value since it's based on both                         * server and share                         */                        if (srv) {                                srv->dev = (dev_t)(str_checksum(server) ^                                                   str_checksum(share));                        }                }        }                /* If we have a connection... */        if (srv) {                /* ... then we're done here.  Give 'em what they came for. */                return srv;        }        /* If we're not asked to connect when a connection doesn't exist... */        if (! connect_if_not_found) {                /* ... then we're done here. */                return NULL;        }	make_nmb_name(&calling, context->netbios_name, 0x0);	make_nmb_name(&called , server, 0x20);	DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));  	DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again:	slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);	zero_ip(&ip);	/* have to open a new connection */	if (!cli_initialise(&c)) {		errno = ENOMEM;		return NULL;	}	if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) {		c.use_kerberos = True;	}	if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) {		c.fallback_after_kerberos = True;	}	c.timeout = context->timeout;        /*         * Force use of port 139 for first try if share is $IPC, empty, or         * null, so browse lists can work         */        if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) {                port_try_first = 139;                port_try_next = 445;        } else {                port_try_first = 445;                port_try_next = 139;        }        c.port = port_try_first;	if (!cli_connect(&c, server_n, &ip)) {                /* First connection attempt failed.  Try alternate port. */                c.port = port_try_next;                if (!cli_connect(&c, server_n, &ip)) {                        cli_shutdown(&c);                        errno = ETIMEDOUT;                        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;		}		else {  /* Try one more time, but ensure we don't loop */		  /* Only try this if server is an IP address ... */		  if (is_ipaddress(server) && !tried_reverse) {		    fstring remote_name;		    struct in_addr rem_ip;		    if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) {		      DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server));		      errno = ETIMEDOUT;		      return NULL;		    }		    tried_reverse++; /* Yuck */		    if (name_status_find("*", 0, 0, rem_ip, remote_name)) {		      make_nmb_name(&called, remote_name, 0x20);		      goto again;		    }		  }		}		errno = ETIMEDOUT;		return NULL;	}  	DEBUG(4,(" session request ok\n"));  	if (!cli_negprot(&c)) {		cli_shutdown(&c);		errno = ETIMEDOUT;		return NULL;	}        username_used = username;	if (!cli_session_setup(&c, username_used, 			       password, strlen(password),			       password, strlen(password),			       workgroup)) {                                /* Failed.  Try an anonymous login, if allowed by flags. */                username_used = "";                if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||                     !cli_session_setup(&c, username_used,                                        password, 1,                                        password, 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 = smbc_errno(context, &c);		cli_shutdown(&c);		return NULL;	}  	DEBUG(4,(" tconx ok\n"));  	/*	 * Ok, we have got a nice connection	 * Let's allocate a server structure.	 */	srv = SMB_MALLOC_P(SMBCSRV);	if (!srv) {		errno = ENOMEM;		goto failed;	}	ZERO_STRUCTP(srv);	srv->cli = c;        srv->cli.allocated = False;	srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));        srv->no_pathinfo = False;        srv->no_pathinfo2 = False;        srv->no_nt_session = False;	/* now add it to the cache (internal or external)  */	/* Let the cache function set errno if it wants to */	errno = 0;	if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) {		int saved_errno = errno;		DEBUG(3, (" Failed to add server to cache\n"));		errno = saved_errno;		if (errno == 0) {			errno = ENOMEM;		}		goto failed;	}		DEBUG(2, ("Server connect ok: //%s/%s: %p\n", 		  server, share, srv));	DLIST_ADD(context->internal->_servers, srv);	return srv; failed:	cli_shutdown(&c);	if (!srv) return NULL;  	SAFE_FREE(srv);	return NULL;}/* * Connect to a server for getting/setting attributes, possibly on an existing * connection.  This works similarly to smbc_server(). */static SMBCSRV *smbc_attr_server(SMBCCTX *context,                 const char *server,                 const char *share,                  fstring workgroup,                 fstring username,                 fstring password,                 POLICY_HND *pol){        struct in_addr ip;	struct cli_state *ipc_cli;	struct rpc_pipe_client *pipe_hnd;        NTSTATUS nt_status;	SMBCSRV *ipc_srv=NULL;        /*         * See if we've already created this special connection.  Reference         * our "special" share name '*IPC$', which is an impossible real share         * name due to the leading asterisk.         */        ipc_srv = find_server(context, server, "*IPC$",                              workgroup, username, password);        if (!ipc_srv) {                /* We didn't find a cached connection.  Get the password */                if (*password == '\0') {                        /* ... then retrieve it now. */                        context->callbacks.auth_fn(server, share,                                                   workgroup, sizeof(fstring),                                                   username, sizeof(fstring),                                                   password, sizeof(fstring));                }                        zero_ip(&ip);                nt_status = cli_full_connection(&ipc_cli,                                                global_myname(), server,                                                 &ip, 0, "IPC$", "?????",                                                  username, workgroup,                                                password, 0,                                                Undefined, NULL);                if (! NT_STATUS_IS_OK(nt_status)) {                        DEBUG(1,("cli_full_connection failed! (%s)\n",                                 nt_errstr(nt_status)));                        errno = ENOTSUP;                        return NULL;                }                ipc_srv = SMB_MALLOC_P(SMBCSRV);                if (!ipc_srv) {                        errno = ENOMEM;                        cli_shutdown(ipc_cli);                        return NULL;                }                ZERO_STRUCTP(ipc_srv);                ipc_srv->cli = *ipc_cli;                ipc_srv->cli.allocated = False;                free(ipc_cli);                if (pol) {                        pipe_hnd = cli_rpc_pipe_open_noauth(&ipc_srv->cli,                                                            PI_LSARPC,                                                            &nt_status);                        if (!pipe_hnd) {                                DEBUG(1, ("cli_nt_session_open fail!\n"));                                errno = ENOTSUP;                                cli_shutdown(&ipc_srv->cli);                                free(ipc_srv);                                return NULL;                        }                        /*                         * Some systems don't support                         * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000                         * so we might as well do it too.                         */                                nt_status = rpccli_lsa_open_policy(                                pipe_hnd,                                ipc_srv->cli.mem_ctx,                                True,                                 GENERIC_EXECUTE_ACCESS,                                pol);                                if (!NT_STATUS_IS_OK(nt_status)) {                                errno = smbc_errno(context, &ipc_srv->cli);                                cli_shutdown(&ipc_srv->cli);                                return NULL;                        }                }                /* now add it to the cache (internal or external) */                errno = 0;      /* let cache function set errno if it likes */                if (context->callbacks.add_cached_srv_fn(context, ipc_srv,                                                         server,                                                         "*IPC$",                                                         workgroup,                                                         username)) {                        DEBUG(3, (" Failed to add server to cache\n"));                        if (errno == 0) {                                errno = ENOMEM;                        }                        cli_shutdown(&ipc_srv->cli);                        free(ipc_srv);                        return NULL;                }                DLIST_ADD(context->internal->_servers, ipc_srv);        }        return ipc_srv;}/* * Routine to open() a file ... */static SMBCFILE *smbc_open_ctx(SMBCCTX *context,              const char *fname,              int flags,              mode_t mode){	fstring server, share, user, password, workgroup;	pstring path;        pstring targetpath;	struct cli_state *targetcli;	SMBCSRV *srv   = NULL;	SMBCFILE *file = NULL;	int fd;	if (!context || !context->internal ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -