00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024
00025
00026
00027
00028 #define BITMAP_BLOCK_SZ 128
00029
00030 static connection_struct *Connections;
00031
00032
00033 static struct bitmap *bmap;
00034 static int num_open;
00035
00036
00037
00038
00039 void conn_init(void)
00040 {
00041 bmap = bitmap_allocate(BITMAP_BLOCK_SZ);
00042 }
00043
00044
00045
00046
00047 int conn_num_open(void)
00048 {
00049 return num_open;
00050 }
00051
00052
00053
00054
00055
00056 BOOL conn_snum_used(int snum)
00057 {
00058 connection_struct *conn;
00059 for (conn=Connections;conn;conn=conn->next) {
00060 if (conn->params->service == snum) {
00061 return(True);
00062 }
00063 }
00064 return(False);
00065 }
00066
00067
00068
00069
00070
00071 connection_struct *conn_find(unsigned cnum)
00072 {
00073 int count=0;
00074 connection_struct *conn;
00075
00076 for (conn=Connections;conn;conn=conn->next,count++) {
00077 if (conn->cnum == cnum) {
00078 if (count > 10) {
00079 DLIST_PROMOTE(Connections, conn);
00080 }
00081 return conn;
00082 }
00083 }
00084
00085 return NULL;
00086 }
00087
00088
00089
00090
00091
00092
00093 connection_struct *conn_new(void)
00094 {
00095 TALLOC_CTX *mem_ctx;
00096 connection_struct *conn;
00097 int i;
00098 int find_offset = 1;
00099
00100 find_again:
00101 i = bitmap_find(bmap, find_offset);
00102
00103 if (i == -1) {
00104
00105 int oldsz = bmap->n;
00106 int newsz = bmap->n + BITMAP_BLOCK_SZ;
00107 struct bitmap * nbmap;
00108
00109 if (newsz <= oldsz) {
00110
00111 DEBUG(0,("ERROR! Out of connection structures\n"));
00112 return NULL;
00113 }
00114
00115 DEBUG(4,("resizing connections bitmap from %d to %d\n",
00116 oldsz, newsz));
00117
00118 nbmap = bitmap_allocate(newsz);
00119 if (!nbmap) {
00120 DEBUG(0,("ERROR! malloc fail.\n"));
00121 return NULL;
00122 }
00123
00124 bitmap_copy(nbmap, bmap);
00125 bitmap_free(bmap);
00126
00127 bmap = nbmap;
00128 find_offset = oldsz;
00129
00130 goto find_again;
00131 }
00132
00133
00134
00135
00136
00137
00138 if (i > 65534) {
00139 DEBUG(0, ("Maximum connection limit reached\n"));
00140 return NULL;
00141 }
00142
00143 if ((mem_ctx=talloc_init("connection_struct"))==NULL) {
00144 DEBUG(0,("talloc_init(connection_struct) failed!\n"));
00145 return NULL;
00146 }
00147
00148 if (!(conn=TALLOC_ZERO_P(mem_ctx, connection_struct)) ||
00149 !(conn->params = TALLOC_P(mem_ctx, struct share_params))) {
00150 DEBUG(0,("TALLOC_ZERO() failed!\n"));
00151 TALLOC_FREE(mem_ctx);
00152 return NULL;
00153 }
00154 conn->mem_ctx = mem_ctx;
00155 conn->cnum = i;
00156
00157 bitmap_set(bmap, i);
00158
00159 num_open++;
00160
00161 string_set(&conn->user,"");
00162 string_set(&conn->dirpath,"");
00163 string_set(&conn->connectpath,"");
00164 string_set(&conn->origpath,"");
00165
00166 DLIST_ADD(Connections, conn);
00167
00168 return conn;
00169 }
00170
00171
00172
00173
00174
00175 void conn_close_all(void)
00176 {
00177 connection_struct *conn, *next;
00178 for (conn=Connections;conn;conn=next) {
00179 next=conn->next;
00180 set_current_service(conn, 0, True);
00181 close_cnum(conn, conn->vuid);
00182 }
00183 }
00184
00185
00186
00187
00188
00189 BOOL conn_idle_all(time_t t, int deadtime)
00190 {
00191 pipes_struct *plist = NULL;
00192 BOOL allidle = True;
00193 connection_struct *conn, *next;
00194
00195 for (conn=Connections;conn;conn=next) {
00196 next=conn->next;
00197
00198
00199 if (conn->lastused != conn->lastused_count) {
00200 conn->lastused = t;
00201 conn->lastused_count = t;
00202 }
00203
00204
00205 if ((t-conn->lastused) > DPTR_IDLE_TIMEOUT) {
00206 dptr_idlecnum(conn);
00207 }
00208
00209 if (conn->num_files_open > 0 || (t-conn->lastused)<deadtime) {
00210 allidle = False;
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219 for (plist = get_first_internal_pipe(); plist; plist = get_next_internal_pipe(plist))
00220 if (plist->pipe_handles && plist->pipe_handles->count)
00221 allidle = False;
00222
00223 return allidle;
00224 }
00225
00226
00227
00228
00229
00230 void conn_clear_vuid_cache(uint16 vuid)
00231 {
00232 connection_struct *conn;
00233 unsigned int i;
00234
00235 for (conn=Connections;conn;conn=conn->next) {
00236 if (conn->vuid == vuid) {
00237 conn->vuid = UID_FIELD_INVALID;
00238 }
00239
00240 for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) {
00241 if (conn->vuid_cache.array[i].vuid == vuid) {
00242 struct vuid_cache_entry *ent = &conn->vuid_cache.array[i];
00243 ent->vuid = UID_FIELD_INVALID;
00244 ent->read_only = False;
00245 ent->admin_user = False;
00246 }
00247 }
00248 }
00249 }
00250
00251
00252
00253
00254
00255 void conn_free_internal(connection_struct *conn)
00256 {
00257 vfs_handle_struct *handle = NULL, *thandle = NULL;
00258 TALLOC_CTX *mem_ctx = NULL;
00259 struct trans_state *state = NULL;
00260
00261
00262 handle = conn->vfs_handles;
00263 while(handle) {
00264 DLIST_REMOVE(conn->vfs_handles, handle);
00265 thandle = handle->next;
00266 if (handle->free_data)
00267 handle->free_data(&handle->data);
00268 handle = thandle;
00269 }
00270
00271
00272 for (state = conn->pending_trans; state; state = state->next) {
00273
00274 SAFE_FREE(state->param);
00275 SAFE_FREE(state->data);
00276 }
00277
00278 free_namearray(conn->veto_list);
00279 free_namearray(conn->hide_list);
00280 free_namearray(conn->veto_oplock_list);
00281 free_namearray(conn->aio_write_behind_list);
00282
00283 string_free(&conn->user);
00284 string_free(&conn->dirpath);
00285 string_free(&conn->connectpath);
00286 string_free(&conn->origpath);
00287
00288 mem_ctx = conn->mem_ctx;
00289 ZERO_STRUCTP(conn);
00290 talloc_destroy(mem_ctx);
00291 }
00292
00293
00294
00295
00296
00297 void conn_free(connection_struct *conn)
00298 {
00299 DLIST_REMOVE(Connections, conn);
00300
00301 bitmap_clear(bmap, conn->cnum);
00302 num_open--;
00303
00304 conn_free_internal(conn);
00305 }
00306
00307
00308
00309
00310
00311
00312
00313 void msg_force_tdis(int msg_type, struct process_id pid, void *buf, size_t len,
00314 void *private_data)
00315 {
00316 connection_struct *conn, *next;
00317 fstring sharename;
00318
00319 fstrcpy(sharename, (const char *)buf);
00320
00321 if (strcmp(sharename, "*") == 0) {
00322 DEBUG(1,("Forcing close of all shares\n"));
00323 conn_close_all();
00324 return;
00325 }
00326
00327 for (conn=Connections;conn;conn=next) {
00328 next=conn->next;
00329 if (strequal(lp_servicename(SNUM(conn)), sharename)) {
00330 DEBUG(1,("Forcing close of share %s cnum=%d\n",
00331 sharename, conn->cnum));
00332 close_cnum(conn, (uint16)-1);
00333 }
00334 }
00335 }