diff options
-rw-r--r-- | source3/lib/conn_tdb.c | 86 | ||||
-rw-r--r-- | source3/lib/messages.c | 22 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 18 | ||||
-rw-r--r-- | source3/smbd/connection.c | 163 | ||||
-rw-r--r-- | source3/utils/net_status.c | 4 | ||||
-rw-r--r-- | source3/utils/smbcontrol.c | 7 | ||||
-rw-r--r-- | source3/utils/status.c | 2 | ||||
-rw-r--r-- | source3/web/statuspage.c | 23 |
8 files changed, 162 insertions, 163 deletions
diff --git a/source3/lib/conn_tdb.c b/source3/lib/conn_tdb.c index e6f491bbfb..979f202df7 100644 --- a/source3/lib/conn_tdb.c +++ b/source3/lib/conn_tdb.c @@ -20,76 +20,94 @@ #include "includes.h" -TDB_CONTEXT *conn_tdb_ctx(BOOL rw) +static struct db_context *connections_db_ctx(BOOL rw) { - static TDB_CONTEXT *tdb; + static struct db_context *db_ctx; - if (tdb != NULL) { - return tdb; + if (db_ctx != NULL) { + return db_ctx; } if (rw) { - tdb = tdb_open_log(lock_path("connections.tdb"), 0, - TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); + db_ctx = db_open(NULL, lock_path("connections.tdb"), 0, + TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR | O_CREAT, 0644); } else { - tdb = tdb_open_log(lock_path("connections.tdb"), 0, - TDB_DEFAULT, O_RDONLY, 0); + db_ctx = db_open(NULL, lock_path("connections.tdb"), 0, + TDB_DEFAULT, O_RDONLY, 0); } - if (tdb == NULL) { - DEBUG(0, ("Could not open connections.tdb: %s\n", - strerror(errno))); + return db_ctx; +} + +struct db_record *connections_fetch_record(TALLOC_CTX *mem_ctx, + TDB_DATA key) +{ + struct db_context *ctx = connections_db_ctx(True); + + if (ctx == NULL) { + return NULL; } - return tdb; + return ctx->fetch_locked(ctx, mem_ctx, key); +} + +struct db_record *connections_fetch_entry(TALLOC_CTX *mem_ctx, + connection_struct *conn, + const char *name) +{ + struct connections_key ckey; + TDB_DATA key; + + ZERO_STRUCT(ckey); + ckey.pid = procid_self(); + ckey.cnum = conn ? conn->cnum : -1; + strlcpy(ckey.name, name, sizeof(ckey.name)); + + key.dsize = sizeof(ckey); + key.dptr = (uint8 *)&ckey; + + return connections_fetch_record(mem_ctx, key); } struct conn_traverse_state { - int (*fn)(TDB_CONTEXT *tdb, + int (*fn)(struct db_record *rec, const struct connections_key *key, const struct connections_data *data, void *private_data); void *private_data; }; -static int conn_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, - TDB_DATA data, void *private_data) +static int conn_traverse_fn(struct db_record *rec, void *private_data) { struct conn_traverse_state *state = (struct conn_traverse_state *)private_data; - if ((key.dsize != sizeof(struct connections_key)) - || (data.dsize != sizeof(struct connections_data))) { + if ((rec->key.dsize != sizeof(struct connections_key)) + || (rec->value.dsize != sizeof(struct connections_data))) { return 0; } - return state->fn( - tdb, (const struct connections_key *)key.dptr, - (const struct connections_data *)data.dptr, - state->private_data); + return state->fn(rec, (const struct connections_key *)rec->key.dptr, + (const struct connections_data *)rec->value.dptr, + state->private_data); } -int connections_traverse(int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, - TDB_DATA data, void *private_data), +int connections_traverse(int (*fn)(struct db_record *rec, + void *private_data), void *private_data) { - TDB_CONTEXT *tdb = conn_tdb_ctx(True); - - if (tdb == NULL) { - DEBUG(5, ("Could not open connections.tdb r/w, trying r/o\n")); - tdb = conn_tdb_ctx(False); - } + struct db_context *ctx = connections_db_ctx(False); - if (tdb == NULL) { + if (ctx == NULL) { return -1; } - return tdb_traverse(tdb, fn, private_data); + return ctx->traverse(ctx, fn, private_data); } -int connections_forall(int (*fn)(TDB_CONTEXT *tdb, +int connections_forall(int (*fn)(struct db_record *rec, const struct connections_key *key, const struct connections_data *data, void *private_data), @@ -105,5 +123,5 @@ int connections_forall(int (*fn)(TDB_CONTEXT *tdb, BOOL connections_init(BOOL rw) { - return (conn_tdb_ctx(rw) != NULL); + return (connections_db_ctx(rw) != NULL); } diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 056286f89a..01683bf9ec 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -96,12 +96,12 @@ struct msg_all { Send one of the messages for the broadcast. ****************************************************************************/ -static int traverse_fn(TDB_CONTEXT *the_tdb, +static int traverse_fn(struct db_record *rec, const struct connections_key *ckey, const struct connections_data *crec, - void *private_data) + void *state) { - struct msg_all *msg_all = (struct msg_all *)private_data; + struct msg_all *msg_all = (struct msg_all *)state; NTSTATUS status; if (crec->cnum != -1) @@ -120,20 +120,14 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, (uint8 *)msg_all->buf, msg_all->len); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { - - TDB_DATA key; - /* If the pid was not found delete the entry from - * connections.tdb */ - - DEBUG(2,("pid %s doesn't exist - deleting connections " - "%d [%s]\n", procid_str_static(&crec->pid), - crec->cnum, crec->servicename)); + /* If the pid was not found delete the entry from connections.tdb */ - key.dptr = (uint8 *)ckey; - key.dsize = sizeof(*ckey); + DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n", + procid_str_static(&crec->pid), crec->cnum, + crec->servicename)); - tdb_delete(the_tdb, key); + rec->delete_rec(rec); } msg_all->n_sent++; return 0; diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index df7cd06b67..06c733fe49 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -52,15 +52,15 @@ struct sess_file_count { Count the entries belonging to a service in the connection db. ****************************************************************************/ -static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p) +static int pipe_enum_fn( struct db_record *rec, void *p) { struct pipe_open_rec prec; struct file_enum_count *fenum = (struct file_enum_count *)p; - if (dbuf.dsize != sizeof(struct pipe_open_rec)) + if (rec->value.dsize != sizeof(struct pipe_open_rec)) return 0; - memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec)); + memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec)); if ( process_exists(prec.pid) ) { struct srvsvc_NetFileInfo3 *f; @@ -124,14 +124,12 @@ static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info /******************************************************************* ********************************************************************/ -/* global needed to make use of the share_mode_forall() callback */ -static struct file_enum_count f_enum_cnt; - static void enum_file_fn( const struct share_mode_entry *e, const char *sharepath, const char *fname, - void *dummy ) + void *private_data ) { - struct file_enum_count *fenum = &f_enum_cnt; + struct file_enum_count *fenum = + (struct file_enum_count *)&private_data; /* If the pid was not found delete the entry from connections.tdb */ @@ -199,11 +197,13 @@ static void enum_file_fn( const struct share_mode_entry *e, static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info, uint32 *count, uint32 *resume ) { + struct file_enum_count f_enum_cnt; + f_enum_cnt.ctx = ctx; f_enum_cnt.count = *count; f_enum_cnt.info = *info; - share_mode_forall( enum_file_fn, NULL ); + share_mode_forall( enum_file_fn, (void *)&f_enum_cnt ); *info = f_enum_cnt.info; *count = f_enum_cnt.count; diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c index 3e4a8a858b..4c4ddbc0f0 100644 --- a/source3/smbd/connection.c +++ b/source3/smbd/connection.c @@ -20,50 +20,30 @@ #include "includes.h" -static void make_conn_key(connection_struct *conn, const char *name, TDB_DATA *pkbuf, struct connections_key *pkey) -{ - ZERO_STRUCTP(pkey); - pkey->pid = procid_self(); - pkey->cnum = conn?conn->cnum:-1; - fstrcpy(pkey->name, name); -#ifdef DEVELOPER - /* valgrind fixer... */ - { - size_t sl = strlen(pkey->name); - if (sizeof(fstring)-sl) - memset(&pkey->name[sl], '\0', sizeof(fstring)-sl); - } -#endif - - pkbuf->dptr = (uint8 *)pkey; - pkbuf->dsize = sizeof(*pkey); -} - /**************************************************************************** Delete a connection record. ****************************************************************************/ BOOL yield_connection(connection_struct *conn, const char *name) { - struct connections_key key; - TDB_DATA kbuf; - TDB_CONTEXT *tdb = conn_tdb_ctx(True); - - if (!tdb) - return False; + struct db_record *rec; + NTSTATUS status; DEBUG(3,("Yielding connection to %s\n",name)); - make_conn_key(conn, name, &kbuf, &key); + if (!(rec = connections_fetch_entry(NULL, conn, name))) { + DEBUG(0, ("connections_fetch_entry failed\n")); + return False; + } - if (tdb_delete(tdb, kbuf) != 0) { - int dbg_lvl = (!conn && (tdb_error(tdb) == TDB_ERR_NOEXIST)) ? 3 : 0; - DEBUG(dbg_lvl,("yield_connection: tdb_delete for name %s failed with error %s.\n", - name, tdb_errorstr(tdb) )); - return (False); + status = rec->delete_rec(rec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG( NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) ? 3 : 0, + ("deleting connection record returned %s\n", + nt_errstr(status))); } - return(True); + return NT_STATUS_IS_OK(status); } struct count_stat { @@ -77,34 +57,36 @@ struct count_stat { Count the entries belonging to a service in the connection db. ****************************************************************************/ -static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *udp) +static int count_fn(struct db_record *rec, + const struct connections_key *ckey, + const struct connections_data *crec, + void *udp) { - struct connections_data crec; struct count_stat *cs = (struct count_stat *)udp; - if (dbuf.dsize != sizeof(crec)) { - return 0; - } - - 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) && (errno == ESRCH)) { + if (cs->Clear && !process_exists(crec->pid) && (errno == ESRCH)) { + NTSTATUS status; DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n", - procid_str_static(&crec.pid), crec.cnum, crec.servicename)); - if (tdb_delete(the_tdb, kbuf) != 0) - DEBUG(0,("count_fn: tdb_delete failed with error %s\n", tdb_errorstr(the_tdb) )); + procid_str_static(&crec->pid), crec->cnum, + crec->servicename)); + + status = rec->delete_rec(rec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("count_fn: tdb_delete failed with error %s\n", + nt_errstr(status))); + } return 0; } if (cs->name) { /* We are counting all the connections to a given share. */ - if (strequal(crec.servicename, cs->name)) { + if (strequal(crec->servicename, cs->name)) { cs->curr_connections++; } } else { @@ -125,7 +107,6 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u int count_current_connections( const char *sharename, BOOL clear ) { struct count_stat cs; - TDB_CONTEXT *tdb = conn_tdb_ctx(True); cs.mypid = sys_getpid(); cs.curr_connections = 0; @@ -137,9 +118,9 @@ int count_current_connections( const char *sharename, BOOL clear ) * as it leads to deadlock. */ - if (tdb_traverse(tdb, count_fn, &cs) == -1) { - DEBUG(0,("count_current_connections: traverse of connections.tdb failed with error %s\n", - tdb_errorstr(tdb) )); + if (connections_forall(count_fn, &cs) == -1) { + DEBUG(0,("count_current_connections: traverse of " + "connections.tdb failed\n")); DEBUGADD(0, ("count_current_connections: connection count of %d might not be accurate", cs.curr_connections)); } @@ -169,18 +150,17 @@ int count_all_current_connections(void) BOOL claim_connection(connection_struct *conn, const char *name, uint32 msg_flags) { - struct connections_key key; + struct db_record *rec; struct connections_data crec; - TDB_DATA kbuf, dbuf; - TDB_CONTEXT *tdb = conn_tdb_ctx(True); + TDB_DATA dbuf; + NTSTATUS status; - if (!tdb) { + DEBUG(5,("claiming [%s]\n", name)); + + if (!(rec = connections_fetch_entry(NULL, conn, name))) { + DEBUG(0, ("connections_fetch_entry failed\n")); return False; } - - DEBUG(5,("claiming %s\n",name)); - - make_conn_key(conn, name, &kbuf, &key); /* fill in the crec */ ZERO_STRUCT(crec); @@ -190,21 +170,26 @@ BOOL claim_connection(connection_struct *conn, const char *name, if (conn) { crec.uid = conn->uid; crec.gid = conn->gid; - safe_strcpy(crec.servicename, - lp_servicename(SNUM(conn)),sizeof(crec.servicename)-1); + strlcpy(crec.servicename, lp_servicename(SNUM(conn)), + sizeof(crec.servicename)); } crec.start = time(NULL); crec.bcast_msg_flags = msg_flags; - safe_strcpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)-1); - safe_strcpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1); + strlcpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)); + strlcpy(crec.addr,conn?conn->client_address:client_addr(), + sizeof(crec.addr)); dbuf.dptr = (uint8 *)&crec; dbuf.dsize = sizeof(crec); - if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = rec->store(rec, dbuf, TDB_REPLACE); + + TALLOC_FREE(rec); + + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("claim_connection: tdb_store failed with error %s.\n", - tdb_errorstr(tdb) )); + nt_errstr(status))); return False; } @@ -213,44 +198,44 @@ BOOL claim_connection(connection_struct *conn, const char *name, BOOL register_message_flags(BOOL doreg, uint32 msg_flags) { - struct connections_key key; + struct db_record *rec; struct connections_data *pcrec; - TDB_DATA kbuf, dbuf; - TDB_CONTEXT *tdb = conn_tdb_ctx(True); - - if (!tdb) - return False; + NTSTATUS status; DEBUG(10,("register_message_flags: %s flags 0x%x\n", doreg ? "adding" : "removing", (unsigned int)msg_flags )); - make_conn_key(NULL, "", &kbuf, &key); + if (!(rec = connections_fetch_entry(NULL, NULL, NULL))) { + DEBUG(0, ("connections_fetch_entry failed\n")); + return False; + } - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) { - DEBUG(0,("register_message_flags: tdb_fetch failed: %s\n", - tdb_errorstr(tdb))); + if (rec->value.dsize != sizeof(struct connections_data)) { + DEBUG(0,("register_message_flags: Got wrong record size\n")); + TALLOC_FREE(rec); return False; } - pcrec = (struct connections_data *)dbuf.dptr; + pcrec = (struct connections_data *)rec->value.dptr; if (doreg) pcrec->bcast_msg_flags |= msg_flags; else pcrec->bcast_msg_flags &= ~msg_flags; - if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = rec->store(rec, rec->value, TDB_REPLACE); + + TALLOC_FREE(rec); + + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("register_message_flags: tdb_store failed: %s.\n", - tdb_errorstr(tdb) )); - SAFE_FREE(dbuf.dptr); + nt_errstr(status))); return False; } DEBUG(10,("register_message_flags: new flags 0x%x\n", (unsigned int)pcrec->bcast_msg_flags )); - SAFE_FREE(dbuf.dptr); return True; } @@ -297,10 +282,10 @@ static void fill_pipe_open_rec( struct pipe_open_rec *prec, smb_np_struct *p ) BOOL store_pipe_opendb( smb_np_struct *p ) { + struct db_record *dbrec; struct pipe_open_rec *prec; TDB_DATA *key; TDB_DATA data; - TDB_CONTEXT *pipe_tdb; BOOL ret = False; if ( (prec = TALLOC_P( NULL, struct pipe_open_rec)) == NULL ) { @@ -315,12 +300,13 @@ BOOL store_pipe_opendb( smb_np_struct *p ) data.dptr = (uint8 *)prec; data.dsize = sizeof(struct pipe_open_rec); - - if ( (pipe_tdb = conn_tdb_ctx(True) ) == NULL ) { + + if (!(dbrec = connections_fetch_record(prec, *key))) { + DEBUG(0, ("connections_fetch_record failed\n")); goto done; } - - ret = (tdb_store( pipe_tdb, *key, data, TDB_REPLACE ) != -1); + + ret = NT_STATUS_IS_OK(dbrec->store(dbrec, data, TDB_REPLACE)); done: TALLOC_FREE( prec ); @@ -332,9 +318,9 @@ done: BOOL delete_pipe_opendb( smb_np_struct *p ) { + struct db_record *dbrec; struct pipe_open_rec *prec; TDB_DATA *key; - TDB_CONTEXT *pipe_tdb; BOOL ret = False; if ( (prec = TALLOC_P( NULL, struct pipe_open_rec)) == NULL ) { @@ -347,11 +333,12 @@ BOOL delete_pipe_opendb( smb_np_struct *p ) goto done; } - if ( (pipe_tdb = conn_tdb_ctx(True) ) == NULL ) { + if (!(dbrec = connections_fetch_record(prec, *key))) { + DEBUG(0, ("connections_fetch_record failed\n")); goto done; } - ret = (tdb_delete( pipe_tdb, *key ) != -1 ); + ret = NT_STATUS_IS_OK(dbrec->delete_rec(dbrec)); done: TALLOC_FREE( prec ); diff --git a/source3/utils/net_status.c b/source3/utils/net_status.c index 88c1789f71..80fba51b37 100644 --- a/source3/utils/net_status.c +++ b/source3/utils/net_status.c @@ -84,7 +84,7 @@ static int net_status_sessions(int argc, const char **argv) return 0; } -static int show_share(TDB_CONTEXT *tdb, +static int show_share(struct db_record *rec, const struct connections_key *key, const struct connections_data *crec, void *state) @@ -134,7 +134,7 @@ static int collect_pid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, return 0; } -static int show_share_parseable(TDB_CONTEXT *tdb, +static int show_share_parseable(struct db_record *rec, const struct connections_key *key, const struct connections_data *crec, void *state) diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 4f388637ad..2b927adb96 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -243,9 +243,10 @@ cleanup: ptrace(PTRACE_DETACH, pid, NULL, NULL); } -static int stack_trace_connection(TDB_CONTEXT * tdb, +static int stack_trace_connection(struct db_record *rec, const struct connections_key *key, - const struct connections_data *conn, + const struct connections_data *crec, + void *priv) { print_stack_trace(procid_to_pid(&conn->pid), (int *)priv); @@ -278,7 +279,7 @@ static BOOL do_daemon_stack_trace(struct messaging_context *msg_ctx, */ print_stack_trace(dest, &count); } else { - connections_traverse(stack_trace_connection, &count); + connections_forall(stack_trace_connection, &count); } return True; diff --git a/source3/utils/status.c b/source3/utils/status.c index aa014c8410..a797c9c4ba 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -188,7 +188,7 @@ static void print_brl(SMB_DEV_T dev, (double)start, (double)size); } -static int traverse_fn1(TDB_CONTEXT *tdb, +static int traverse_fn1(struct db_record *rec, const struct connections_key *key, const struct connections_data *crec, void *state) diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c index 2071561e2e..cd7b23d864 100644 --- a/source3/web/statuspage.c +++ b/source3/web/statuspage.c @@ -167,15 +167,14 @@ static void print_share_mode(const struct share_mode_entry *e, /* kill off any connections chosen by the user */ -static int traverse_fn1(TDB_CONTEXT *tdb, +static int traverse_fn1(struct db_record *rec, const struct connections_key *key, const struct connections_data *crec, - void* state) + void *private_data) { if (crec->cnum == -1 && process_exists(crec->pid)) { char buf[30]; - slprintf(buf, sizeof(buf)-1,"kill_%s", - procid_str_static(&crec->pid)); + slprintf(buf,sizeof(buf)-1,"kill_%s", procid_str_static(&crec->pid)); if (cgi_variable(buf)) { kill_pid(crec->pid); sleep(SLEEP_TIME); @@ -185,10 +184,10 @@ static int traverse_fn1(TDB_CONTEXT *tdb, } /* traversal fn for showing machine connections */ -static int traverse_fn2(TDB_CONTEXT *tdb, - const struct connections_key *key, - const struct connections_data *crec, - void* state) +static int traverse_fn2(struct db_record *rec, + const struct connections_key *key, + const struct connections_data *crec, + void *private_data) { if (crec->cnum == -1 || !process_exists(crec->pid) || procid_equal(&crec->pid, &smbd_pid)) @@ -210,10 +209,10 @@ static int traverse_fn2(TDB_CONTEXT *tdb, } /* traversal fn for showing share connections */ -static int traverse_fn3(TDB_CONTEXT *tdb, - const struct connections_key *key, - const struct connections_data *crec, - void* state) +static int traverse_fn3(struct db_record *rec, + const struct connections_key *key, + const struct connections_data *crec, + void *private_data) { if (crec->cnum == -1 || !process_exists(crec->pid)) return 0; |