s3:smbXsrv_tcon: add smbXsrv_tcon_global_traverse()
authorGregor Beck <gbeck@sernet.de>
Tue, 28 Aug 2012 13:35:58 +0000 (15:35 +0200)
committerMichael Adam <obnox@samba.org>
Fri, 19 Oct 2012 10:15:00 +0000 (12:15 +0200)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
source3/smbd/globals.h
source3/smbd/smbXsrv_tcon.c

index 6509dda37c9963efc7411d09c3316514382110b2..4a86697d48d29a1a4f9ef4c7124606db32730888 100644 (file)
@@ -427,6 +427,10 @@ NTSTATUS smb2srv_tcon_lookup(struct smbXsrv_session *session,
                             uint32_t tree_id, NTTIME now,
                             struct smbXsrv_tcon **tcon);
 NTSTATUS smb2srv_tcon_disconnect_all(struct smbXsrv_session *session);
+struct smbXsrv_tcon_global0;
+NTSTATUS smbXsrv_tcon_global_traverse(
+                       int (*fn)(struct smbXsrv_tcon_global0 *, void *),
+                       void *private_data);
 
 NTSTATUS smbXsrv_open_global_init(void);
 NTSTATUS smbXsrv_open_create(struct smbXsrv_connection *conn,
index 9f8162a6a61215625cca58b91cc008eb7f699dce..49da84ddfec0f4576b4953328e953d738b5c3061 100644 (file)
@@ -1164,3 +1164,73 @@ NTSTATUS smb2srv_tcon_disconnect_all(struct smbXsrv_session *session)
 
        return smbXsrv_tcon_disconnect_all(session->tcon_table, vuid);
 }
+
+struct smbXsrv_tcon_global_traverse_state {
+       int (*fn)(struct smbXsrv_tcon_global0 *, void *);
+       void *private_data;
+};
+
+static int smbXsrv_tcon_global_traverse_fn(struct db_record *rec, void *data)
+{
+       int ret = -1;
+       struct smbXsrv_tcon_global_traverse_state *state =
+               (struct smbXsrv_tcon_global_traverse_state*)data;
+       TDB_DATA key = dbwrap_record_get_key(rec);
+       TDB_DATA val = dbwrap_record_get_value(rec);
+       DATA_BLOB blob = data_blob_const(val.dptr, val.dsize);
+       struct smbXsrv_tcon_globalB global_blob;
+       enum ndr_err_code ndr_err;
+       TALLOC_CTX *frame = talloc_stackframe();
+
+       ndr_err = ndr_pull_struct_blob(&blob, frame, &global_blob,
+                       (ndr_pull_flags_fn_t)ndr_pull_smbXsrv_tcon_globalB);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(1,("Invalid record in smbXsrv_tcon_global.tdb:"
+                        "key '%s' ndr_pull_struct_blob - %s\n",
+                        hex_encode_talloc(frame, key.dptr, key.dsize),
+                        ndr_errstr(ndr_err)));
+               goto done;
+       }
+
+       if (global_blob.version != SMBXSRV_VERSION_0) {
+               DEBUG(1,("Invalid record in smbXsrv_tcon_global.tdb:"
+                        "key '%s' unsuported version - %d\n",
+                        hex_encode_talloc(frame, key.dptr, key.dsize),
+                        (int)global_blob.version));
+               goto done;
+       }
+
+       ret = state->fn(global_blob.info.info0, state->private_data);
+done:
+       TALLOC_FREE(frame);
+       return ret;
+}
+
+NTSTATUS smbXsrv_tcon_global_traverse(
+                       int (*fn)(struct smbXsrv_tcon_global0 *, void *),
+                       void *private_data)
+{
+       NTSTATUS status;
+       int count = 0;
+       struct smbXsrv_tcon_global_traverse_state state = {
+               .fn = fn,
+               .private_data = private_data,
+       };
+
+       become_root();
+       status = smbXsrv_tcon_global_init();
+       if (!NT_STATUS_IS_OK(status)) {
+               unbecome_root();
+               DEBUG(0, ("Failed to initialize tcon_global: %s\n",
+                         nt_errstr(status)));
+               return status;
+       }
+
+       status = dbwrap_traverse_read(smbXsrv_tcon_global_db_ctx,
+                                     smbXsrv_tcon_global_traverse_fn,
+                                     &state,
+                                     &count);
+       unbecome_root();
+
+       return status;
+}