| 1 | /* 
 | 
|---|
| 2 |    Unix SMB/CIFS implementation.
 | 
|---|
| 3 | 
 | 
|---|
| 4 |    NTPTR base code
 | 
|---|
| 5 | 
 | 
|---|
| 6 |    Copyright (C) Stefan (metze) Metzmacher 2005
 | 
|---|
| 7 | 
 | 
|---|
| 8 |    This program is free software; you can redistribute it and/or modify
 | 
|---|
| 9 |    it under the terms of the GNU General Public License as published by
 | 
|---|
| 10 |    the Free Software Foundation; either version 3 of the License, or
 | 
|---|
| 11 |    (at your option) any later version.
 | 
|---|
| 12 |    
 | 
|---|
| 13 |    This program is distributed in the hope that it will be useful,
 | 
|---|
| 14 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 15 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 16 |    GNU General Public License for more details.
 | 
|---|
| 17 |    
 | 
|---|
| 18 |    You should have received a copy of the GNU General Public License
 | 
|---|
| 19 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
|---|
| 20 | */
 | 
|---|
| 21 | /*
 | 
|---|
| 22 |   this implements the core code for all NTPTR modules. Backends register themselves here.
 | 
|---|
| 23 | */
 | 
|---|
| 24 | 
 | 
|---|
| 25 | #include "includes.h"
 | 
|---|
| 26 | #include "ntptr/ntptr.h"
 | 
|---|
| 27 | #include "param/param.h"
 | 
|---|
| 28 | 
 | 
|---|
| 29 | /* the list of currently registered NTPTR backends */
 | 
|---|
| 30 | static struct ntptr_backend {
 | 
|---|
| 31 |         const struct ntptr_ops *ops;
 | 
|---|
| 32 | } *backends = NULL;
 | 
|---|
| 33 | static int num_backends;
 | 
|---|
| 34 | 
 | 
|---|
| 35 | /*
 | 
|---|
| 36 |   register a NTPTR backend. 
 | 
|---|
| 37 | 
 | 
|---|
| 38 |   The 'name' can be later used by other backends to find the operations
 | 
|---|
| 39 |   structure for this backend.
 | 
|---|
| 40 | */
 | 
|---|
| 41 | NTSTATUS ntptr_register(const void *_ops)
 | 
|---|
| 42 | {
 | 
|---|
| 43 |         const struct ntptr_ops *ops = _ops;
 | 
|---|
| 44 |         struct ntptr_ops *new_ops;
 | 
|---|
| 45 | 
 | 
|---|
| 46 |         if (ntptr_backend_byname(ops->name) != NULL) {
 | 
|---|
| 47 |                 /* its already registered! */
 | 
|---|
| 48 |                 DEBUG(0,("NTPTR backend '%s' already registered\n", 
 | 
|---|
| 49 |                          ops->name));
 | 
|---|
| 50 |                 return NT_STATUS_OBJECT_NAME_COLLISION;
 | 
|---|
| 51 |         }
 | 
|---|
| 52 | 
 | 
|---|
| 53 |         backends = realloc_p(backends, struct ntptr_backend, num_backends+1);
 | 
|---|
| 54 |         if (!backends) {
 | 
|---|
| 55 |                 smb_panic("out of memory in ntptr_register");
 | 
|---|
| 56 |         }
 | 
|---|
| 57 | 
 | 
|---|
| 58 |         new_ops = smb_xmemdup(ops, sizeof(*ops));
 | 
|---|
| 59 |         new_ops->name = smb_xstrdup(ops->name);
 | 
|---|
| 60 | 
 | 
|---|
| 61 |         backends[num_backends].ops = new_ops;
 | 
|---|
| 62 | 
 | 
|---|
| 63 |         num_backends++;
 | 
|---|
| 64 | 
 | 
|---|
| 65 |         DEBUG(3,("NTPTR backend '%s'\n", 
 | 
|---|
| 66 |                  ops->name));
 | 
|---|
| 67 | 
 | 
|---|
| 68 |         return NT_STATUS_OK;
 | 
|---|
| 69 | }
 | 
|---|
| 70 | 
 | 
|---|
| 71 | NTSTATUS ntptr_init(struct loadparm_context *lp_ctx)
 | 
|---|
| 72 | {
 | 
|---|
| 73 | #define _MODULE_PROTO(init) extern NTSTATUS init(void);
 | 
|---|
| 74 |         STATIC_ntptr_MODULES_PROTO;
 | 
|---|
| 75 |         init_module_fn static_init[] = { STATIC_ntptr_MODULES };
 | 
|---|
| 76 |         init_module_fn *shared_init = load_samba_modules(NULL, lp_ctx, "ntptr");
 | 
|---|
| 77 | 
 | 
|---|
| 78 |         run_init_functions(static_init);
 | 
|---|
| 79 |         run_init_functions(shared_init);
 | 
|---|
| 80 | 
 | 
|---|
| 81 |         talloc_free(shared_init);
 | 
|---|
| 82 |         
 | 
|---|
| 83 |         return NT_STATUS_OK;    
 | 
|---|
| 84 | }
 | 
|---|
| 85 | 
 | 
|---|
| 86 | 
 | 
|---|
| 87 | /*
 | 
|---|
| 88 |   return the operations structure for a named backend
 | 
|---|
| 89 | */
 | 
|---|
| 90 | const struct ntptr_ops *ntptr_backend_byname(const char *name)
 | 
|---|
| 91 | {
 | 
|---|
| 92 |         int i;
 | 
|---|
| 93 | 
 | 
|---|
| 94 |         for (i=0;i<num_backends;i++) {
 | 
|---|
| 95 |                 if (strcmp(backends[i].ops->name, name) == 0) {
 | 
|---|
| 96 |                         return backends[i].ops;
 | 
|---|
| 97 |                 }
 | 
|---|
| 98 |         }
 | 
|---|
| 99 | 
 | 
|---|
| 100 |         return NULL;
 | 
|---|
| 101 | }
 | 
|---|
| 102 | 
 | 
|---|
| 103 | 
 | 
|---|
| 104 | /*
 | 
|---|
| 105 |   return the NTPTR interface version, and the size of some critical types
 | 
|---|
| 106 |   This can be used by backends to either detect compilation errors, or provide
 | 
|---|
| 107 |   multiple implementations for different smbd compilation options in one module
 | 
|---|
| 108 | */
 | 
|---|
| 109 | static const struct ntptr_critical_sizes critical_sizes = {
 | 
|---|
| 110 |         .interface_version              = NTPTR_INTERFACE_VERSION,
 | 
|---|
| 111 |         .sizeof_ntptr_critical_sizes    = sizeof(struct ntptr_critical_sizes),
 | 
|---|
| 112 |         .sizeof_ntptr_context           = sizeof(struct ntptr_context),
 | 
|---|
| 113 |         .sizeof_ntptr_ops               = sizeof(struct ntptr_ops),
 | 
|---|
| 114 | };
 | 
|---|
| 115 | const struct ntptr_critical_sizes *ntptr_interface_version(void)
 | 
|---|
| 116 | {
 | 
|---|
| 117 |         return &critical_sizes;
 | 
|---|
| 118 | }
 | 
|---|
| 119 | 
 | 
|---|
| 120 | /*
 | 
|---|
| 121 |   create a ntptr_context with a specified NTPTR backend
 | 
|---|
| 122 | */
 | 
|---|
| 123 | NTSTATUS ntptr_init_context(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx,
 | 
|---|
| 124 |                             struct loadparm_context *lp_ctx,
 | 
|---|
| 125 |                             const char *providor, struct ntptr_context **_ntptr)
 | 
|---|
| 126 | {
 | 
|---|
| 127 |         NTSTATUS status;
 | 
|---|
| 128 |         struct ntptr_context *ntptr;
 | 
|---|
| 129 | 
 | 
|---|
| 130 |         if (!providor) {
 | 
|---|
| 131 |                 return NT_STATUS_INTERNAL_ERROR;
 | 
|---|
| 132 |         }
 | 
|---|
| 133 | 
 | 
|---|
| 134 |         ntptr = talloc(mem_ctx, struct ntptr_context);
 | 
|---|
| 135 |         NT_STATUS_HAVE_NO_MEMORY(ntptr);
 | 
|---|
| 136 |         ntptr->private_data     = NULL;
 | 
|---|
| 137 |         ntptr->ops              = ntptr_backend_byname(providor);
 | 
|---|
| 138 |         ntptr->ev_ctx           = ev_ctx;
 | 
|---|
| 139 |         ntptr->lp_ctx           = lp_ctx;
 | 
|---|
| 140 | 
 | 
|---|
| 141 |         if (!ntptr->ops) {
 | 
|---|
| 142 |                 DEBUG(1,("ntptr_init_context: failed to find NTPTR providor='%s'\n",
 | 
|---|
| 143 |                          providor));
 | 
|---|
| 144 |                 return NT_STATUS_INTERNAL_ERROR;
 | 
|---|
| 145 |         }
 | 
|---|
| 146 | 
 | 
|---|
| 147 |         status = ntptr->ops->init_context(ntptr);
 | 
|---|
| 148 |         NT_STATUS_NOT_OK_RETURN(status);
 | 
|---|
| 149 | 
 | 
|---|
| 150 |         *_ntptr = ntptr;
 | 
|---|
| 151 |         return NT_STATUS_OK;
 | 
|---|
| 152 | }
 | 
|---|