move to SAFE_FREE()
[Samba.git] / source3 / smbd / conn.c
blob08704927c561f1d5125d419f63700bec63f221bb
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Manage connections_struct structures
5 Copyright (C) Andrew Tridgell 1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 extern int DEBUGLEVEL;
26 /* set these to define the limits of the server. NOTE These are on a
27 per-client basis. Thus any one machine can't connect to more than
28 MAX_CONNECTIONS services, but any number of machines may connect at
29 one time. */
30 #define MAX_CONNECTIONS 128
32 static connection_struct *Connections;
34 /* number of open connections */
35 static struct bitmap *bmap;
36 static int num_open;
38 /****************************************************************************
39 init the conn structures
40 ****************************************************************************/
41 void conn_init(void)
43 bmap = bitmap_allocate(MAX_CONNECTIONS);
46 /****************************************************************************
47 return the number of open connections
48 ****************************************************************************/
49 int conn_num_open(void)
51 return num_open;
55 /****************************************************************************
56 check if a snum is in use
57 ****************************************************************************/
58 BOOL conn_snum_used(int snum)
60 connection_struct *conn;
61 for (conn=Connections;conn;conn=conn->next) {
62 if (conn->service == snum) {
63 return(True);
66 return(False);
70 /****************************************************************************
71 find a conn given a cnum
72 ****************************************************************************/
73 connection_struct *conn_find(int cnum)
75 int count=0;
76 connection_struct *conn;
78 for (conn=Connections;conn;conn=conn->next,count++) {
79 if (conn->cnum == cnum) {
80 if (count > 10) {
81 DLIST_PROMOTE(Connections, conn);
83 return conn;
87 return NULL;
91 /****************************************************************************
92 find first available connection slot, starting from a random position.
93 The randomisation stops problems with the server dieing and clients
94 thinking the server is still available.
95 ****************************************************************************/
96 connection_struct *conn_new(void)
98 connection_struct *conn;
99 int i;
101 i = bitmap_find(bmap, 1);
103 if (i == -1) {
104 DEBUG(1,("ERROR! Out of connection structures\n"));
105 return NULL;
108 conn = (connection_struct *)malloc(sizeof(*conn));
109 if (!conn) return NULL;
111 ZERO_STRUCTP(conn);
112 conn->cnum = i;
114 bitmap_set(bmap, i);
116 num_open++;
118 string_set(&conn->user,"");
119 string_set(&conn->dirpath,"");
120 string_set(&conn->connectpath,"");
121 string_set(&conn->origpath,"");
123 DLIST_ADD(Connections, conn);
125 return conn;
128 /****************************************************************************
129 close all conn structures
130 ****************************************************************************/
131 void conn_close_all(void)
133 connection_struct *conn, *next;
134 for (conn=Connections;conn;conn=next) {
135 next=conn->next;
136 close_cnum(conn, (uint16)-1);
140 /****************************************************************************
141 idle inactive connections
142 ****************************************************************************/
143 BOOL conn_idle_all(time_t t, int deadtime)
145 BOOL allidle = True;
146 connection_struct *conn, *next;
148 for (conn=Connections;conn;conn=next) {
149 next=conn->next;
150 /* close dirptrs on connections that are idle */
151 if ((t-conn->lastused) > DPTR_IDLE_TIMEOUT)
152 dptr_idlecnum(conn);
154 if (conn->num_files_open > 0 ||
155 (t-conn->lastused)<deadtime)
156 allidle = False;
159 return allidle;
162 /****************************************************************************
163 Free a conn structure.
164 ****************************************************************************/
166 void conn_free(connection_struct *conn)
168 /* Free vfs_connection_struct */
170 #ifdef HAVE_LIBDL
171 if (conn->dl_handle != NULL) {
172 /* Close dlopen() handle */
173 dlclose(conn->dl_handle);
175 #endif /* HAVE_LIBDL */
177 DLIST_REMOVE(Connections, conn);
179 if (conn->ngroups && conn->groups) {
180 SAFE_FREE(conn->groups);
181 conn->ngroups = 0;
184 delete_nt_token(&conn->nt_user_token);
185 free_namearray(conn->veto_list);
186 free_namearray(conn->hide_list);
187 free_namearray(conn->veto_oplock_list);
189 string_free(&conn->user);
190 string_free(&conn->dirpath);
191 string_free(&conn->connectpath);
192 string_free(&conn->origpath);
194 bitmap_clear(bmap, conn->cnum);
195 num_open--;
197 ZERO_STRUCTP(conn);
198 SAFE_FREE(conn);
202 /****************************************************************************
203 receive a smbcontrol message to forcibly unmount a share
204 the message contains just a share name and all instances of that
205 share are unmounted
206 the special sharename '*' forces unmount of all shares
207 ****************************************************************************/
208 void msg_force_tdis(int msg_type, pid_t pid, void *buf, size_t len)
210 connection_struct *conn, *next;
211 fstring sharename;
213 fstrcpy(sharename, buf);
215 if (strcmp(sharename, "*") == 0) {
216 DEBUG(1,("Forcing close of all shares\n"));
217 conn_close_all();
218 return;
221 for (conn=Connections;conn;conn=next) {
222 next=conn->next;
223 if (strequal(lp_servicename(conn->service), sharename)) {
224 DEBUG(1,("Forcing close of share %s cnum=%d\n",
225 sharename, conn->cnum));
226 close_cnum(conn, (uint16)-1);