diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/VFS/README.netatalk | 18 | ||||
-rw-r--r-- | examples/VFS/netatalk.c | 430 | ||||
-rw-r--r-- | examples/sam/Makefile.in | 28 | ||||
-rw-r--r-- | examples/sam/README | 29 | ||||
-rw-r--r-- | examples/sam/sam_skel.c | 250 |
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; +} |