summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/VFS/README.netatalk18
-rw-r--r--examples/VFS/netatalk.c430
-rw-r--r--examples/sam/Makefile.in28
-rw-r--r--examples/sam/README29
-rw-r--r--examples/sam/sam_skel.c250
5 files changed, 755 insertions, 0 deletions
diff --git a/examples/VFS/README.netatalk b/examples/VFS/README.netatalk
new file mode 100644
index 00000000000..70f6eea316d
--- /dev/null
+++ b/examples/VFS/README.netatalk
@@ -0,0 +1,18 @@
+There is the new netatalk module both for HEAD.
+This one has some difference from previous module:
+
+-- it doesn't care about creating of .AppleDouble forks, just keeps ones in
+sync;
+
+-- if share in smb.conf doesn't contain .AppleDouble item in hide or veto
+list, it will be added automatically.
+
+To my way of thinking, module became more lightweight and speedy.
+
+How to compile:
+
+you should place proper netatalk.c into examples/VFS/ then run 'configure'
+from source/ and then run 'make' from examples/VFS/.
+
+add string 'vfs object = <path_to_netatalk_so>/netatlk.so' to smb.conf. It may
+be defined either as global or as share-specific parameter.
diff --git a/examples/VFS/netatalk.c b/examples/VFS/netatalk.c
new file mode 100644
index 00000000000..353be36e6f0
--- /dev/null
+++ b/examples/VFS/netatalk.c
@@ -0,0 +1,430 @@
+/*
+ * AppleTalk VFS module for Samba-3.x
+ *
+ * Copyright (C) Alexei Kotovich, 2002
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <sys/stat.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <includes.h>
+#include <vfs.h>
+
+#define APPLEDOUBLE ".AppleDouble"
+#define ADOUBLEMODE 0777
+
+/* atalk functions */
+
+static int atalk_build_paths(TALLOC_CTX *ctx, const char *path,
+ const char *fname, char **adbl_path, char **orig_path,
+ SMB_STRUCT_STAT *adbl_info, SMB_STRUCT_STAT *orig_info);
+
+static int atalk_unlink_file(const char *path);
+
+static struct vfs_ops default_vfs_ops; /* For passthrough operation */
+static struct smb_vfs_handle_struct *atalk_handle;
+
+static int atalk_get_path_ptr(char *path)
+{
+ int i = 0;
+ int ptr = 0;
+
+ for (i = 0; path[i]; i ++) {
+ if (path[i] == '/')
+ ptr = i;
+ /* get out some 'spam';) from win32's file name */
+ else if (path[i] == ':') {
+ path[i] = '\0';
+ break;
+ }
+ }
+
+ return ptr;
+}
+
+static int atalk_build_paths(TALLOC_CTX *ctx, const char *path, const char *fname,
+ char **adbl_path, char **orig_path,
+ SMB_STRUCT_STAT *adbl_info, SMB_STRUCT_STAT *orig_info)
+{
+ int ptr0 = 0;
+ int ptr1 = 0;
+ char *dname = 0;
+ char *name = 0;
+
+ if (!ctx || !path || !fname || !adbl_path || !orig_path ||
+ !adbl_info || !orig_info)
+ return -1;
+#if 0
+ DEBUG(3, ("ATALK: PATH: %s[%s]\n", path, fname));
+#endif
+ if (strstr(path, APPLEDOUBLE) || strstr(fname, APPLEDOUBLE)) {
+ DEBUG(3, ("ATALK: path %s[%s] already contains %s\n", path, fname, APPLEDOUBLE));
+ return -1;
+ }
+
+ if (fname[0] == '.') ptr0 ++;
+ if (fname[1] == '/') ptr0 ++;
+
+ *orig_path = talloc_asprintf(ctx, "%s/%s", path, &fname[ptr0]);
+
+ /* get pointer to last '/' */
+ ptr1 = atalk_get_path_ptr(*orig_path);
+
+ sys_lstat(*orig_path, orig_info);
+
+ if (S_ISDIR(orig_info->st_mode)) {
+ *adbl_path = talloc_asprintf(ctx, "%s/%s/%s/",
+ path, &fname[ptr0], APPLEDOUBLE);
+ } else {
+ dname = talloc_strdup(ctx, *orig_path);
+ dname[ptr1] = '\0';
+ name = *orig_path;
+ *adbl_path = talloc_asprintf(ctx, "%s/%s/%s",
+ dname, APPLEDOUBLE, &name[ptr1 + 1]);
+ }
+#if 0
+ DEBUG(3, ("ATALK: DEBUG:\n%s\n%s\n", *orig_path, *adbl_path));
+#endif
+ sys_lstat(*adbl_path, adbl_info);
+ return 0;
+}
+
+static int atalk_unlink_file(const char *path)
+{
+ int ret = 0;
+
+ become_root();
+ ret = unlink(path);
+ unbecome_root();
+
+ return ret;
+}
+
+static void atalk_add_to_list(name_compare_entry **list)
+{
+ int i, count = 0;
+ name_compare_entry *new_list = 0;
+ name_compare_entry *cur_list = 0;
+
+ cur_list = *list;
+
+ if (cur_list) {
+ for (i = 0, count = 0; cur_list[i].name; i ++, count ++) {
+ if (strstr(cur_list[i].name, APPLEDOUBLE))
+ return;
+ }
+ }
+
+ if (!(new_list = calloc(1,
+ (count == 0 ? 1 : count + 1) * sizeof(name_compare_entry))))
+ return;
+
+ for (i = 0; i < count; i ++) {
+ new_list[i].name = strdup(cur_list[i].name);
+ new_list[i].is_wild = cur_list[i].is_wild;
+ }
+
+ new_list[i].name = strdup(APPLEDOUBLE);
+ new_list[i].is_wild = False;
+
+ free_namearray(*list);
+
+ *list = new_list;
+ new_list = 0;
+ cur_list = 0;
+}
+
+static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
+{
+ int n;
+ char *dpath;
+ struct dirent **namelist;
+
+ if (!path) return;
+
+ n = scandir(path, &namelist, 0, alphasort);
+ if (n < 0) {
+ return;
+ } else {
+ while (n --) {
+ if (strcmp(namelist[n]->d_name, ".") == 0 ||
+ strcmp(namelist[n]->d_name, "..") == 0)
+ continue;
+ if (!(dpath = talloc_asprintf(ctx, "%s/%s",
+ path, namelist[n]->d_name)))
+ continue;
+ atalk_unlink_file(dpath);
+ free(namelist[n]);
+ }
+ }
+}
+
+/* Disk operations */
+
+/* Directory operations */
+
+DIR *atalk_opendir(struct connection_struct *conn, const char *fname)
+{
+ DIR *ret = 0;
+
+ ret = default_vfs_ops.opendir(conn, fname);
+
+ /*
+ * when we try to perform delete operation upon file which has fork
+ * in ./.AppleDouble and this directory wasn't hidden by Samba,
+ * MS Windows explorer causes the error: "Cannot find the specified file"
+ * There is some workaround to avoid this situation, i.e. if
+ * connection has not .AppleDouble entry in either veto or hide
+ * list then it would be nice to add one.
+ */
+
+ atalk_add_to_list(&conn->hide_list);
+ atalk_add_to_list(&conn->veto_list);
+
+ return ret;
+}
+
+static int atalk_rmdir(struct connection_struct *conn, const char *path)
+{
+ BOOL add = False;
+ TALLOC_CTX *ctx = 0;
+ char *dpath;
+
+ if (!conn || !conn->origpath || !path) goto exit_rmdir;
+
+ /* due to there is no way to change bDeleteVetoFiles variable
+ * from this module, gotta use talloc stuff..
+ */
+
+ strstr(path, APPLEDOUBLE) ? (add = False) : (add = True);
+
+ if (!(ctx = talloc_init_named("remove_directory")))
+ goto exit_rmdir;
+
+ if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
+ conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
+ goto exit_rmdir;
+
+ atalk_rrmdir(ctx, dpath);
+
+exit_rmdir:
+ talloc_destroy(ctx);
+ return default_vfs_ops.rmdir(conn, path);
+}
+
+/* File operations */
+
+static int atalk_rename(struct connection_struct *conn, const char *old, const char *new)
+{
+ int ret = 0;
+ char *adbl_path = 0;
+ char *orig_path = 0;
+ SMB_STRUCT_STAT adbl_info;
+ SMB_STRUCT_STAT orig_info;
+ TALLOC_CTX *ctx;
+
+ ret = default_vfs_ops.rename(conn, old, new);
+
+ if (!conn || !old) return ret;
+
+ if (!(ctx = talloc_init_named("rename_file")))
+ return ret;
+
+ if (atalk_build_paths(ctx, conn->origpath, old, &adbl_path, &orig_path,
+ &adbl_info, &orig_info) != 0)
+ return ret;
+
+ if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
+ DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
+ goto exit_rename;
+ }
+
+ atalk_unlink_file(adbl_path);
+
+exit_rename:
+ talloc_destroy(ctx);
+ return ret;
+}
+
+static int atalk_unlink(struct connection_struct *conn, const char *path)
+{
+ int ret = 0, i;
+ char *adbl_path = 0;
+ char *orig_path = 0;
+ SMB_STRUCT_STAT adbl_info;
+ SMB_STRUCT_STAT orig_info;
+ TALLOC_CTX *ctx;
+
+ ret = default_vfs_ops.unlink(conn, path);
+
+ if (!conn || !path) return ret;
+
+ /* no .AppleDouble sync if veto or hide list is empty,
+ * otherwise "Cannot find the specified file" error will be caused
+ */
+
+ if (!conn->veto_list) return ret;
+ if (!conn->hide_list) return ret;
+
+ for (i = 0; conn->veto_list[i].name; i ++) {
+ if (strstr(conn->veto_list[i].name, APPLEDOUBLE))
+ break;
+ }
+
+ if (!conn->veto_list[i].name) {
+ for (i = 0; conn->hide_list[i].name; i ++) {
+ if (strstr(conn->hide_list[i].name, APPLEDOUBLE))
+ break;
+ else {
+ DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
+ APPLEDOUBLE));
+ return ret;
+ }
+ }
+ }
+
+ if (!(ctx = talloc_init_named("unlink_file")))
+ return ret;
+
+ if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ &adbl_info, &orig_info) != 0)
+ return ret;
+
+ if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
+ DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
+ goto exit_unlink;
+ }
+
+ atalk_unlink_file(adbl_path);
+
+exit_unlink:
+ talloc_destroy(ctx);
+ return ret;
+}
+
+static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+{
+ int ret = 0;
+ char *adbl_path = 0;
+ char *orig_path = 0;
+ SMB_STRUCT_STAT adbl_info;
+ SMB_STRUCT_STAT orig_info;
+ TALLOC_CTX *ctx;
+
+ ret = default_vfs_ops.chmod(conn, path, mode);
+
+ if (!conn || !path) return ret;
+
+ if (!(ctx = talloc_init_named("chmod_file")))
+ return ret;
+
+ if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ &adbl_info, &orig_info) != 0)
+ return ret;
+
+ if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
+ DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
+ goto exit_chmod;
+ }
+
+ chmod(adbl_path, ADOUBLEMODE);
+
+exit_chmod:
+ talloc_destroy(ctx);
+ return ret;
+}
+
+static int atalk_chown(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+{
+ int ret = 0;
+ char *adbl_path = 0;
+ char *orig_path = 0;
+ SMB_STRUCT_STAT adbl_info;
+ SMB_STRUCT_STAT orig_info;
+ TALLOC_CTX *ctx;
+
+ ret = default_vfs_ops.chown(conn, path, uid, gid);
+
+ if (!conn || !path) return ret;
+
+ if (!(ctx = talloc_init_named("chown_file")))
+ return ret;
+
+ if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ &adbl_info, &orig_info) != 0)
+ return ret;
+
+ if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
+ DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
+ goto exit_chown;
+ }
+
+ chown(adbl_path, uid, gid);
+
+exit_chown:
+ talloc_destroy(ctx);
+ return ret;
+}
+
+static vfs_op_tuple atalk_ops[] = {
+
+ /* Directory operations */
+
+ {atalk_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {atalk_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* File operations */
+
+ {atalk_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
+ {atalk_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
+ {atalk_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
+ {atalk_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* Finish VFS operations definition */
+
+ {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
+vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
+ struct smb_vfs_handle_struct *vfs_handle)
+{
+ *vfs_version = SMB_VFS_INTERFACE_VERSION;
+ memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
+
+ atalk_handle = vfs_handle;
+
+ DEBUG(3, ("ATALK: vfs module loaded\n"));
+ return atalk_ops;
+}
+
+/* VFS finalization function. */
+void vfs_done(connection_struct *conn)
+{
+ DEBUG(3, ("ATALK: vfs module unloaded\n"));
+}
diff --git a/examples/sam/Makefile.in b/examples/sam/Makefile.in
new file mode 100644
index 00000000000..d5df346a8c4
--- /dev/null
+++ b/examples/sam/Makefile.in
@@ -0,0 +1,28 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LDSHFLAGS = -shared
+srcdir = @builddir@
+FLAGS = $(CFLAGS) -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper -I. $(CPPFLAGS) -I$(srcdir)
+
+SAM_OBJS = sam_skel.so
+
+# Default target
+
+default: $(SAM_OBJS)
+
+# Pattern rules
+
+%.so: %.o
+ $(CC) $(LDSHFLAGS) $(LDFLAGS) -o $@ $<
+
+%.o: %.c
+ $(CC) $(FLAGS) -c $<
+
+# Misc targets
+
+clean:
+ rm -rf .libs
+ rm -f core *~ *% *.bak \
+ $(SAM_OBJ) $(SAM_OBJS)
diff --git a/examples/sam/README b/examples/sam/README
new file mode 100644
index 00000000000..9e9fbb26db3
--- /dev/null
+++ b/examples/sam/README
@@ -0,0 +1,29 @@
+README for Samba SAM Database examples
+====================================================
+26-08-2002 Stefan (metze) Metzmacher <metze@metzemix.de>
+
+Every module MUST have a sam_version() function.
+
+this is defined in include/sam.h:
+#define SAM_MODULE_VERSIONING_MAGIC \
+int sam_version(void)\
+{\
+ return SAM_INTERFACE_VERSION;\
+}
+
+You MUST add this line inside a module:
+SAM_MODULE_VERSIONING_MAGIC
+
+
+The sam_skel.c file in this directory contains a very basic example of
+a SAM plugin. It just prints the name of the function that is executed using
+DEBUG. Maybe it's nice to include some of the arguments to the function in the
+future too..
+
+New SAM plugins should go into the samba lib directory, (/usr/lib/samba/
+for most distributions) and should be prefixed with 'sam_' and should go into the
+subdir sam/. The SAM subsystem will search in /usr/lib/samba/sam and fall back to
+/usr/lib/samba/ .
+An example path would be:
+/usr/lib/samba/sam/sam_skel.so
+
diff --git a/examples/sam/sam_skel.c b/examples/sam/sam_skel.c
new file mode 100644
index 00000000000..da3a3758947
--- /dev/null
+++ b/examples/sam/sam_skel.c
@@ -0,0 +1,250 @@
+/*
+ Unix SMB/CIFS implementation.
+ this is a skeleton for SAM backend modules.
+
+ Copyright (C) Stefan (metze) Metzmacher 2002
+ Copyright (C) Jelmer Vernooij 2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static int sam_skel_debug_level = DBGC_SAM;
+
+#undef DBGC_CLASS
+#define DBGC_CLASS sam_skel_debug_level
+
+/* define the version of the SAM interface */
+SAM_MODULE_VERSIONING_MAGIC
+
+/* General API */
+
+NTSTATUS sam_skel_get_sec_desc(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, const DOM_SID *sid, SEC_DESC **sd)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_set_sec_desc(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, const DOM_SID *sid, const SEC_DESC *sd)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS sam_skel_lookup_sid(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, const DOM_SID *sid, char **name, uint32 *type)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_lookup_name(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, const char *name, DOM_SID **sid, uint32 *type)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Domain API */
+
+NTSTATUS sam_skel_update_domain(const SAM_METHODS *sam_methods, const SAM_DOMAIN_HANDLE *domain)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_get_domain_handle(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint32 access_desired, SAM_DOMAIN_HANDLE **domain)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Account API */
+
+NTSTATUS sam_skel_create_account(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *group_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_add_account(const SAM_METHODS *sam_methods, const SAM_ACCOUNT_HANDLE *account)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_update_account(const SAM_METHODS *sam_methods, const SAM_ACCOUNT_HANDLE *account)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_delete_account(const SAM_METHODS *sam_methods, const SAM_ACCOUNT_HANDLE *account)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_enum_accounts(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint16 acct_ctrl, uint32 *account_count, SAM_ACCOUNT_ENUM **accounts)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS sam_skel_get_account_by_sid(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *accountsid, SAM_ACCOUNT_HANDLE **account)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_get_account_by_name(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *name, SAM_ACCOUNT_HANDLE **account)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Group API */
+
+NTSTATUS sam_skel_create_group(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *account_name, uint16 group_ctrl, SAM_GROUP_HANDLE **group)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_add_group(const SAM_METHODS *sam_methods, const SAM_GROUP_HANDLE *group)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_update_group(const SAM_METHODS *sam_methods, const SAM_GROUP_HANDLE *group)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_delete_group(const SAM_METHODS *sam_methods, const SAM_GROUP_HANDLE *group)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_enum_groups(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint16 group_ctrl, uint32 *groups_count, SAM_GROUP_ENUM **groups)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_get_group_by_sid(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *groupsid, SAM_GROUP_HANDLE **group)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_get_group_by_name(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *name, SAM_GROUP_HANDLE **group)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS sam_skel_add_member_to_group(const SAM_METHODS *sam_methods, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_delete_member_from_group(const SAM_METHODS *sam_methods, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_skel_enum_groupmembers(const SAM_METHODS *sam_methods, const SAM_GROUP_HANDLE *group, uint32 *members_count, SAM_GROUP_MEMBER **members)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS sam_skel_get_groups_of_sid(const SAM_METHODS *sam_methods, const NT_USER_TOKEN *access_token, const DOM_SID **sids, uint16 group_ctrl, uint32 *group_count, SAM_GROUP_ENUM **groups)
+{
+ DEBUG(0,("sam_skel: %s was called!\n",__FUNCTION__));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS sam_init(SAM_METHODS *sam_methods, const char *module_params)
+{
+ /* Functions your SAM module doesn't provide should be set
+ * to NULL */
+
+ sam_methods->sam_get_sec_desc = sam_skel_get_sec_desc;
+ sam_methods->sam_set_sec_desc = sam_skel_set_sec_desc;
+
+ sam_methods->sam_lookup_sid = sam_skel_lookup_sid;
+ sam_methods->sam_lookup_name = sam_skel_lookup_name;
+
+ /* Domain API */
+
+ sam_methods->sam_update_domain = sam_skel_update_domain;
+ sam_methods->sam_get_domain_handle = sam_skel_get_domain_handle;
+
+ /* Account API */
+
+ sam_methods->sam_create_account = sam_skel_create_account;
+ sam_methods->sam_add_account = sam_skel_add_account;
+ sam_methods->sam_update_account = sam_skel_update_account;
+ sam_methods->sam_delete_account = sam_skel_delete_account;
+ sam_methods->sam_enum_accounts = sam_skel_enum_accounts;
+
+ sam_methods->sam_get_account_by_sid = sam_skel_get_account_by_sid;
+ sam_methods->sam_get_account_by_name = sam_skel_get_account_by_name;
+
+ /* Group API */
+
+ sam_methods->sam_create_group = sam_skel_create_group;
+ sam_methods->sam_add_group = sam_skel_add_group;
+ sam_methods->sam_update_group = sam_skel_update_group;
+ sam_methods->sam_delete_group = sam_skel_delete_group;
+ sam_methods->sam_enum_groups = sam_skel_enum_groups;
+ sam_methods->sam_get_group_by_sid = sam_skel_get_group_by_sid;
+ sam_methods->sam_get_group_by_name = sam_skel_get_group_by_name;
+
+ sam_methods->sam_add_member_to_group = sam_skel_add_member_to_group;
+ sam_methods->sam_delete_member_from_group = sam_skel_delete_member_from_group;
+ sam_methods->sam_enum_groupmembers = sam_skel_enum_groupmembers;
+
+ sam_methods->sam_get_groups_of_sid = sam_skel_get_groups_of_sid;
+
+ sam_methods->free_private_data = NULL;
+
+
+ sam_skel_debug_level = debug_add_class("sam_skel");
+ if (sam_skel_debug_level == -1) {
+ sam_skel_debug_level = DBGC_SAM;
+ DEBUG(0, ("sam_skel: Couldn't register custom debugging class!\n"));
+ } else DEBUG(2, ("sam_skel: Debug class number of 'sam_skel': %d\n", sam_skel_debug_level));
+
+ if(module_params)
+ DEBUG(0, ("Starting 'sam_skel' with parameters '%s' for domain %s\n", module_params, sam_methods->domain_name));
+ else
+ DEBUG(0, ("Starting 'sam_skel' for domain %s without paramters\n", sam_methods->domain_name));
+
+ return NT_STATUS_OK;
+}