summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/groupdb/mapping.c2
-rw-r--r--source3/smbd/connection.c48
2 files changed, 29 insertions, 21 deletions
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c
index 5b844e93d2..2f258ea724 100644
--- a/source3/groupdb/mapping.c
+++ b/source3/groupdb/mapping.c
@@ -670,7 +670,7 @@ BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids)
gr = grp->gr_mem[0];
DEBUG(10, ("getting members\n"));
- while (gr && (*gr != (char)NULL)) {
+ while (gr && (*gr != (char)'\0')) {
(*uid)=Realloc((*uid), sizeof(uid_t)*(*num_uids+1));
if( (pwd=getpwnam(gr)) !=NULL) {
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 5a3fcc2975..edbc49777e 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -84,18 +84,19 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u
memcpy(&crec, dbuf.dptr, sizeof(crec));
- if (crec.cnum == -1)
+ if (crec.cnum == -1)
return 0;
- /* if the pid was not found delete the entry from connections.tdb */
- if (cs->Clear && !process_exists(crec.pid)) {
+ /* If the pid was not found delete the entry from connections.tdb */
+
+ if (cs->Clear && !process_exists(crec.pid) && (errno == ESRCH)) {
DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n",
(unsigned int)crec.pid, crec.cnum, crec.name));
tdb_delete(the_tdb, kbuf);
return 0;
}
- if (cs && strequal(crec.name, cs->name))
+ if (strequal(crec.name, cs->name))
cs->curr_connections++;
return 0;
@@ -109,7 +110,9 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
{
struct connections_key key;
struct connections_data crec;
- TDB_DATA kbuf, dbuf;
+ TDB_DATA kbuf, dbuf, lockkey;
+ BOOL rec_locked = False;
+ BOOL ret = True;
if (!tdb) {
tdb = tdb_open(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST,
@@ -130,18 +133,30 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
cs.name = lp_servicename(SNUM(conn));
cs.Clear = Clear;
+ lockkey.dptr = cs.name;
+ lockkey.dsize = strlen(cs.name)+1;
+
/*
- * Go through and count the connections
+ * Go through and count the connections with hash chain representing the service name
+ * locked. This is slow but removes race conditions. JRA.
*/
+
+ if (tdb_chainlock(tdb, lockkey))
+ return False;
+
+ rec_locked = True;
+
if (tdb_traverse(tdb, count_fn, &cs) == -1) {
DEBUG(0,("claim_connection: traverse of connections.tdb failed.\n"));
- return False;
+ ret = False;
+ goto out;
}
if (cs.curr_connections >= max_connections) {
DEBUG(1,("claim_connection: Max connections (%d) exceeded for %s\n",
max_connections, name ));
- return False;
+ ret = False;
+ goto out;
}
}
@@ -176,19 +191,12 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
dbuf.dsize = sizeof(crec);
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0)
- return False;
+ ret = False;
- return True;
-}
+ out:
-#if 0
-/****************************************************************************
- Use the count function to clean any dead records. Shouldn't be needed...
-****************************************************************************/
+ if (rec_locked)
+ tdb_chainunlock(tdb, lockkey);
-void clean_connection_db(void)
-{
- if (tdb_traverse(tdb, count_fn, NULL) == -1)
- DEBUG(0,("clean_connection_db: traverse of connections.tdb failed.\n"));
+ return ret;
}
-#endif