diff options
Diffstat (limited to 'source3/sam')
-rw-r--r-- | source3/sam/account.c | 305 | ||||
-rw-r--r-- | source3/sam/group.c | 193 | ||||
-rw-r--r-- | source3/sam/gums.c | 173 | ||||
-rw-r--r-- | source3/sam/gums_api.c | 1426 | ||||
-rw-r--r-- | source3/sam/gums_helper.c | 383 | ||||
-rw-r--r-- | source3/sam/gums_tdbsam2.c | 1220 | ||||
-rw-r--r-- | source3/sam/interface.c | 1338 |
7 files changed, 0 insertions, 5038 deletions
diff --git a/source3/sam/account.c b/source3/sam/account.c deleted file mode 100644 index b8336146cd..0000000000 --- a/source3/sam/account.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Jeremy Allison 1996-2001 - Copyright (C) Luke Kenneth Casson Leighton 1996-1998 - Copyright (C) Gerald (Jerry) Carter 2000-2001 - Copyright (C) Andrew Bartlett 2001-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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_SAM - -/************************************************************ - Fill the SAM_ACCOUNT_HANDLE with default values. - ***********************************************************/ - -static void sam_fill_default_account(SAM_ACCOUNT_HANDLE *account) -{ - ZERO_STRUCT(account->private); /* Don't touch the talloc context */ - - /* Don't change these timestamp settings without a good reason. - They are important for NT member server compatibility. */ - - /* FIXME: We should actually call get_nt_time_max() or sthng - * here */ - unix_to_nt_time(&(account->private.logoff_time),get_time_t_max()); - unix_to_nt_time(&(account->private.kickoff_time),get_time_t_max()); - unix_to_nt_time(&(account->private.pass_must_change_time),get_time_t_max()); - account->private.unknown_1 = 0x00ffffff; /* don't know */ - account->private.logon_divs = 168; /* hours per week */ - account->private.hours_len = 21; /* 21 times 8 bits = 168 */ - memset(account->private.hours, 0xff, account->private.hours_len); /* available at all hours */ - account->private.unknown_2 = 0x00000000; /* don't know */ - account->private.unknown_3 = 0x000004ec; /* don't know */ -} - -static void destroy_sam_talloc(SAM_ACCOUNT_HANDLE **account) -{ - if (*account) { - data_blob_clear_free(&((*account)->private.lm_pw)); - data_blob_clear_free(&((*account)->private.nt_pw)); - if((*account)->private.plaintext_pw!=NULL) - memset((*account)->private.plaintext_pw,'\0',strlen((*account)->private.plaintext_pw)); - - talloc_destroy((*account)->mem_ctx); - *account = NULL; - } -} - - -/********************************************************************** - Alloc memory and initialises a SAM_ACCOUNT_HANDLE on supplied mem_ctx. -***********************************************************************/ - -NTSTATUS sam_init_account_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT_HANDLE **account) -{ - SMB_ASSERT(*account != NULL); - - if (!mem_ctx) { - DEBUG(0,("sam_init_account_talloc: mem_ctx was NULL!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - *account=(SAM_ACCOUNT_HANDLE *)talloc(mem_ctx, sizeof(SAM_ACCOUNT_HANDLE)); - - if (*account==NULL) { - DEBUG(0,("sam_init_account_talloc: error while allocating memory\n")); - return NT_STATUS_NO_MEMORY; - } - - (*account)->mem_ctx = mem_ctx; - - (*account)->free_fn = NULL; - - sam_fill_default_account(*account); - - return NT_STATUS_OK; -} - - -/************************************************************* - Alloc memory and initialises a struct sam_passwd. - ************************************************************/ - -NTSTATUS sam_init_account(SAM_ACCOUNT_HANDLE **account) -{ - TALLOC_CTX *mem_ctx; - NTSTATUS nt_status; - - mem_ctx = talloc_init("sam internal SAM_ACCOUNT_HANDLE allocation"); - - if (!mem_ctx) { - DEBUG(0,("sam_init_account: error while doing talloc_init()\n")); - return NT_STATUS_NO_MEMORY; - } - - if (!NT_STATUS_IS_OK(nt_status = sam_init_account_talloc(mem_ctx, account))) { - talloc_destroy(mem_ctx); - return nt_status; - } - - (*account)->free_fn = destroy_sam_talloc; - - return NT_STATUS_OK; -} - -/** - * Free the contents of the SAM_ACCOUNT_HANDLE, but not the structure. - * - * Also wipes the LM and NT hashes and plaintext password from - * memory. - * - * @param account SAM_ACCOUNT_HANDLE to free members of. - **/ - -static void sam_free_account_contents(SAM_ACCOUNT_HANDLE *account) -{ - - /* Kill off sensitive data. Free()ed by the - talloc mechinism */ - - data_blob_clear_free(&(account->private.lm_pw)); - data_blob_clear_free(&(account->private.nt_pw)); - if (account->private.plaintext_pw) - memset(account->private.plaintext_pw,'\0',strlen(account->private.plaintext_pw)); -} - - -/************************************************************ - Reset the SAM_ACCOUNT_HANDLE and free the NT/LM hashes. - ***********************************************************/ - -NTSTATUS sam_reset_sam(SAM_ACCOUNT_HANDLE *account) -{ - SMB_ASSERT(account != NULL); - - sam_free_account_contents(account); - - sam_fill_default_account(account); - - return NT_STATUS_OK; -} - - -/************************************************************ - Free the SAM_ACCOUNT_HANDLE and the member pointers. - ***********************************************************/ - -NTSTATUS sam_free_account(SAM_ACCOUNT_HANDLE **account) -{ - SMB_ASSERT(*account != NULL); - - sam_free_account_contents(*account); - - if ((*account)->free_fn) { - (*account)->free_fn(account); - } - - return NT_STATUS_OK; -} - - -/********************************************************** - Encode the account control bits into a string. - length = length of string to encode into (including terminating - null). length *MUST BE MORE THAN 2* ! - **********************************************************/ - -char *sam_encode_acct_ctrl(uint16 acct_ctrl, size_t length) -{ - static fstring acct_str; - size_t i = 0; - - acct_str[i++] = '['; - - if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N'; - if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D'; - if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H'; - if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T'; - if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U'; - if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M'; - if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W'; - if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S'; - if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L'; - if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X'; - if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I'; - - for ( ; i < length - 2 ; i++ ) - acct_str[i] = ' '; - - i = length - 2; - acct_str[i++] = ']'; - acct_str[i++] = '\0'; - - return acct_str; -} - -/********************************************************** - Decode the account control bits from a string. - **********************************************************/ - -uint16 sam_decode_acct_ctrl(const char *p) -{ - uint16 acct_ctrl = 0; - BOOL finished = False; - - /* - * Check if the account type bits have been encoded after the - * NT password (in the form [NDHTUWSLXI]). - */ - - if (*p != '[') - return 0; - - for (p++; *p && !finished; p++) { - switch (*p) { - case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ } - case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ } - case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ } - case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ } - case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ } - case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ } - case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ } - case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } - case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } - case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ } - case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ } - case ' ': { break; } - case ':': - case '\n': - case '\0': - case ']': - default: { finished = True; } - } - } - - return acct_ctrl; -} - -/************************************************************* - Routine to set 32 hex password characters from a 16 byte array. -**************************************************************/ - -void sam_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl) -{ - if (pwd != NULL) { - int i; - for (i = 0; i < 16; i++) - slprintf(&p[i*2], 3, "%02X", pwd[i]); - } else { - if (acct_ctrl & ACB_PWNOTREQ) - safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33); - else - safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33); - } -} - -/************************************************************* - Routine to get the 32 hex characters and turn them - into a 16 byte array. -**************************************************************/ - -BOOL sam_gethexpwd(const char *p, unsigned char *pwd) -{ - int i; - unsigned char lonybble, hinybble; - char *hexchars = "0123456789ABCDEF"; - char *p1, *p2; - - if (!p) - return (False); - - for (i = 0; i < 32; i += 2) { - hinybble = toupper(p[i]); - lonybble = toupper(p[i + 1]); - - p1 = strchr(hexchars, hinybble); - p2 = strchr(hexchars, lonybble); - - if (!p1 || !p2) - return (False); - - hinybble = PTR_DIFF(p1, hexchars); - lonybble = PTR_DIFF(p2, hexchars); - - pwd[i / 2] = (hinybble << 4) | lonybble; - } - return (True); -} diff --git a/source3/sam/group.c b/source3/sam/group.c deleted file mode 100644 index 101e3dd7ce..0000000000 --- a/source3/sam/group.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SAM_GROUP_HANDLE /SAM_GROUP_ENUM helpers - - Copyright (C) Stefan (metze) Metzmacher 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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_SAM - -/************************************************************ - Fill the SAM_GROUP_HANDLE with default values. - ***********************************************************/ - -static void sam_fill_default_group(SAM_GROUP_HANDLE *group) -{ - ZERO_STRUCT(group->private); /* Don't touch the talloc context */ - -} - -static void destroy_sam_group_handle_talloc(SAM_GROUP_HANDLE **group) -{ - if (*group) { - - talloc_destroy((*group)->mem_ctx); - *group = NULL; - } -} - - -/********************************************************************** - Alloc memory and initialises a SAM_GROUP_HANDLE on supplied mem_ctx. -***********************************************************************/ - -NTSTATUS sam_init_group_talloc(TALLOC_CTX *mem_ctx, SAM_GROUP_HANDLE **group) -{ - SMB_ASSERT(*group != NULL); - - if (!mem_ctx) { - DEBUG(0,("sam_init_group_talloc: mem_ctx was NULL!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - *group=(SAM_GROUP_HANDLE *)talloc(mem_ctx, sizeof(SAM_GROUP_HANDLE)); - - if (*group==NULL) { - DEBUG(0,("sam_init_group_talloc: error while allocating memory\n")); - return NT_STATUS_NO_MEMORY; - } - - (*group)->mem_ctx = mem_ctx; - - (*group)->free_fn = NULL; - - sam_fill_default_group(*group); - - return NT_STATUS_OK; -} - - -/************************************************************* - Alloc memory and initialises a struct SAM_GROUP_HANDLE. - ************************************************************/ - -NTSTATUS sam_init_group(SAM_GROUP_HANDLE **group) -{ - TALLOC_CTX *mem_ctx; - NTSTATUS nt_status; - - mem_ctx = talloc_init("sam internal SAM_GROUP_HANDLE allocation"); - - if (!mem_ctx) { - DEBUG(0,("sam_init_group: error while doing talloc_init()\n")); - return NT_STATUS_NO_MEMORY; - } - - if (!NT_STATUS_IS_OK(nt_status = sam_init_group_talloc(mem_ctx, group))) { - talloc_destroy(mem_ctx); - return nt_status; - } - - (*group)->free_fn = destroy_sam_group_handle_talloc; - - return NT_STATUS_OK; -} - - -/************************************************************ - Reset the SAM_GROUP_HANDLE. - ***********************************************************/ - -NTSTATUS sam_reset_group(SAM_GROUP_HANDLE *group) -{ - SMB_ASSERT(group != NULL); - - sam_fill_default_group(group); - - return NT_STATUS_OK; -} - - -/************************************************************ - Free the SAM_GROUP_HANDLE and the member pointers. - ***********************************************************/ - -NTSTATUS sam_free_group(SAM_ACCOUNT_HANDLE **group) -{ - SMB_ASSERT(*group != NULL); - - if ((*group)->free_fn) { - (*group)->free_fn(group); - } - - return NT_STATUS_OK; -} - - -/********************************************************** - Encode the group control bits into a string. - length = length of string to encode into (including terminating - null). length *MUST BE MORE THAN 2* ! - **********************************************************/ - -char *sam_encode_acct_ctrl(uint16 group_ctrl, size_t length) -{ - static fstring group_str; - size_t i = 0; - - group_str[i++] = '['; - - if (group_ctrl & GCB_LOCAL_GROUP ) group_str[i++] = 'L'; - if (group_ctrl & GCB_GLOBAL_GROUP ) group_str[i++] = 'G'; - - for ( ; i < length - 2 ; i++ ) - group_str[i] = ' '; - - i = length - 2; - group_str[i++] = ']'; - group_str[i++] = '\0'; - - return group_str; -} - -/********************************************************** - Decode the group control bits from a string. - **********************************************************/ - -uint16 sam_decode_group_ctrl(const char *p) -{ - uint16 group_ctrl = 0; - BOOL finished = False; - - /* - * Check if the account type bits have been encoded after the - * NT password (in the form [NDHTUWSLXI]). - */ - - if (*p != '[') - return 0; - - for (p++; *p && !finished; p++) { - switch (*p) { - case 'L': { group_ctrl |= GCB_LOCAL_GROUP; break; /* 'L'ocal Aliases Group. */ } - case 'G': { group_ctrl |= GCB_GLOBAL_GROUP; break; /* 'G'lobal Domain Group. */ } - - case ' ': { break; } - case ':': - case '\n': - case '\0': - case ']': - default: { finished = True; } - } - } - - return group_ctrl; -} - diff --git a/source3/sam/gums.c b/source3/sam/gums.c deleted file mode 100644 index b719153584..0000000000 --- a/source3/sam/gums.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Grops and Users Management System initializations. - Copyright (C) Simo Sorce 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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_SAM - -#define GMV_MAJOR 0 -#define GMV_MINOR 1 - -static GUMS_FUNCTIONS *gums_backend = NULL; - -static struct gums_init_function_entry *backends = NULL; - -static void lazy_initialize_gums(void) -{ - static BOOL initialized = False; - - if (initialized) - return; - - static_init_gums; - initialized = True; -} - -static struct gums_init_function_entry *gums_find_backend_entry(const char *name); - -NTSTATUS gums_register_module(int version, const char *name, gums_init_function init_fn) -{ - struct gums_init_function_entry *entry = backends; - - if (version != GUMS_INTERFACE_VERSION) { - DEBUG(0,("Can't register gums backend!\n" - "You tried to register a gums module with" - "GUMS_INTERFACE_VERSION %d, while this version" - "of samba uses version %d\n", version, - GUMS_INTERFACE_VERSION)); - - return NT_STATUS_OBJECT_TYPE_MISMATCH; - } - - if (!name || !init_fn) { - return NT_STATUS_INVALID_PARAMETER; - } - - DEBUG(5,("Attempting to register gums backend %s\n", name)); - - /* Check for duplicates */ - if (gums_find_backend_entry(name)) { - DEBUG(0,("There already is a gums backend registered" - "with the name %s!\n", name)); - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - entry = smb_xmalloc(sizeof(struct gums_init_function_entry)); - entry->name = smb_xstrdup(name); - entry->init_fn = init_fn; - - DLIST_ADD(backends, entry); - DEBUG(5,("Successfully added gums backend '%s'\n", name)); - return NT_STATUS_OK; -} - -static struct gums_init_function_entry *gums_find_backend_entry(const char *name) -{ - struct gums_init_function_entry *entry = backends; - - while (entry) { - if (strcmp(entry->name, name) == 0) - return entry; - entry = entry->next; - } - - return NULL; -} - -NTSTATUS gums_setup_backend(const char *backend) -{ - - TALLOC_CTX *mem_ctx; - char *module_name = smb_xstrdup(backend); - char *p, *module_data = NULL; - struct gums_init_function_entry *entry; - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - lazy_initialize_gums(); - - p = strchr(module_name, ':'); - if (p) { - *p = 0; - module_data = p+1; - trim_string(module_data, " ", " "); - } - - trim_string(module_name, " ", " "); - - DEBUG(5,("Attempting to find a gums backend to match %s (%s)\n", backend, module_name)); - - entry = gums_find_backend_entry(module_name); - - /* Try to find a module that contains this module */ - if (!entry) { - DEBUG(2,("No builtin backend found, trying to load plugin\n")); - if(NT_STATUS_IS_OK(smb_probe_module("gums", module_name)) && !(entry = gums_find_backend_entry(module_name))) { - DEBUG(0,("Plugin is available, but doesn't register gums backend %s\n", module_name)); - SAFE_FREE(module_name); - return NT_STATUS_UNSUCCESSFUL; - } - } - - /* No such backend found */ - if(!entry) { - DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name)); - SAFE_FREE(module_name); - return NT_STATUS_INVALID_PARAMETER; - } - - DEBUG(5,("Found gums backend %s\n", module_name)); - - /* free current functions structure if any */ - if (gums_backend) { - gums_backend->free_private_data(gums_backend->private_data); - talloc_destroy(gums_backend->mem_ctx); - gums_backend = NULL; - } - - /* allocate a new GUMS_FUNCTIONS structure and memory context */ - mem_ctx = talloc_init("gums_backend (%s)", module_name); - if (!mem_ctx) - return NT_STATUS_NO_MEMORY; - gums_backend = talloc(mem_ctx, sizeof(GUMS_FUNCTIONS)); - if (!gums_backend) - return NT_STATUS_NO_MEMORY; - gums_backend->mem_ctx = mem_ctx; - - /* init the requested backend module */ - if (NT_STATUS_IS_OK(ret = entry->init_fn(gums_backend, module_data))) { - DEBUG(5,("gums backend %s has a valid init\n", backend)); - } else { - DEBUG(0,("gums backend %s did not correctly init (error was %s)\n", backend, nt_errstr(ret))); - } - SAFE_FREE(module_name); - return ret; -} - -NTSTATUS get_gums_fns(GUMS_FUNCTIONS **fns) -{ - if (gums_backend != NULL) { - *fns = gums_backend; - return NT_STATUS_OK; - } - - DEBUG(2, ("get_gums_fns: unable to get gums functions! backend uninitialized?\n")); - return NT_STATUS_UNSUCCESSFUL; -} diff --git a/source3/sam/gums_api.c b/source3/sam/gums_api.c deleted file mode 100644 index 5aafa7695f..0000000000 --- a/source3/sam/gums_api.c +++ /dev/null @@ -1,1426 +0,0 @@ -/* - Unix SMB/CIFS implementation. - GUMS structures - Copyright (C) Simo Sorce 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" - -/* Functions to get/set info from a GUMS object */ - -NTSTATUS gums_create_object(GUMS_OBJECT **obj, uint32 type) -{ - TALLOC_CTX *mem_ctx; - GUMS_OBJECT *go; - NTSTATUS ret; - - mem_ctx = talloc_init("gums_create_object"); - if (!mem_ctx) { - DEBUG(0, ("gums_create_object: Out of memory!\n")); - *obj = NULL; - return NT_STATUS_NO_MEMORY; - } - - go = talloc_zero(mem_ctx, sizeof(GUMS_OBJECT)); - if (!go) { - DEBUG(0, ("gums_create_object: Out of memory!\n")); - talloc_destroy(mem_ctx); - *obj = NULL; - return NT_STATUS_NO_MEMORY; - } - - go->mem_ctx = mem_ctx; - go->type = type; - go->version = GUMS_OBJECT_VERSION; - - switch(type) { - case GUMS_OBJ_DOMAIN: - go->domain = (GUMS_DOMAIN *)talloc_zero(mem_ctx, sizeof(GUMS_DOMAIN)); - if (!(go->domain)) { - ret = NT_STATUS_NO_MEMORY; - DEBUG(0, ("gums_create_object: Out of memory!\n")); - goto error; - } - - break; - -/* - case GUMS_OBJ_WORKSTATION_TRUST: - case GUMS_OBJ_SERVER_TRUST: - case GUMS_OBJ_DOMAIN_TRUST: -*/ - case GUMS_OBJ_NORMAL_USER: - go->user = (GUMS_USER *)talloc_zero(mem_ctx, sizeof(GUMS_USER)); - if (!(go->user)) { - ret = NT_STATUS_NO_MEMORY; - DEBUG(0, ("gums_create_object: Out of memory!\n")); - goto error; - } - gums_set_user_acct_ctrl(go, ACB_NORMAL); - gums_set_user_hours(go, 0, NULL); - - break; - - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - go->group = (GUMS_GROUP *)talloc_zero(mem_ctx, sizeof(GUMS_GROUP)); - if (!(go->group)) { - ret = NT_STATUS_NO_MEMORY; - DEBUG(0, ("gums_create_object: Out of memory!\n")); - goto error; - } - - break; - - default: - /* TODO: throw error */ - ret = NT_STATUS_OBJECT_TYPE_MISMATCH; - goto error; - } - - *obj = go; - return NT_STATUS_OK; - -error: - talloc_destroy(go->mem_ctx); - *obj = NULL; - return ret; -} - -NTSTATUS gums_create_privilege(GUMS_PRIVILEGE **priv) -{ - TALLOC_CTX *mem_ctx; - GUMS_PRIVILEGE *pri; - - mem_ctx = talloc_init("gums_create_privilege"); - if (!mem_ctx) { - DEBUG(0, ("gums_create_privilege: Out of memory!\n")); - *priv = NULL; - return NT_STATUS_NO_MEMORY; - } - - pri = talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE)); - if (!pri) { - DEBUG(0, ("gums_create_privilege: Out of memory!\n")); - talloc_destroy(mem_ctx); - *priv = NULL; - return NT_STATUS_NO_MEMORY; - } - - pri->mem_ctx = mem_ctx; - pri->version = GUMS_PRIVILEGE_VERSION; - - *priv = pri; - return NT_STATUS_OK; -} - -NTSTATUS gums_destroy_object(GUMS_OBJECT **obj) -{ - if (!obj || !(*obj)) - return NT_STATUS_INVALID_PARAMETER; - - if ((*obj)->mem_ctx) - talloc_destroy((*obj)->mem_ctx); - *obj = NULL; - - return NT_STATUS_OK; -} - -NTSTATUS gums_destroy_privilege(GUMS_PRIVILEGE **priv) -{ - if (!priv || !(*priv)) - return NT_STATUS_INVALID_PARAMETER; - - if ((*priv)->mem_ctx) - talloc_destroy((*priv)->mem_ctx); - *priv = NULL; - - return NT_STATUS_OK; -} - -void gums_reset_object(GUMS_OBJECT *go) -{ - go->seq_num = 0; - go->sid = NULL; - go->name = NULL; - go->description = NULL; - - switch(go->type) { - case GUMS_OBJ_DOMAIN: - memset(go->domain, 0, sizeof(GUMS_DOMAIN)); - break; - -/* - case GUMS_OBJ_WORKSTATION_TRUST: - case GUMS_OBJ_SERVER_TRUST: - case GUMS_OBJ_DOMAIN_TRUST: -*/ - case GUMS_OBJ_NORMAL_USER: - memset(go->user, 0, sizeof(GUMS_USER)); - gums_set_user_acct_ctrl(go, ACB_NORMAL); - break; - - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - memset(go->group, 0, sizeof(GUMS_GROUP)); - break; - - default: - return; - } -} - -uint32 gums_get_object_type(const GUMS_OBJECT *obj) -{ - if (!obj) - return 0; - - return obj->type; -} - -uint32 gums_get_object_seq_num(const GUMS_OBJECT *obj) -{ - if (!obj) - return 0; - - return obj->seq_num; -} - -uint32 gums_get_object_version(const GUMS_OBJECT *obj) -{ - if (!obj) - return 0; - - return obj->version; -} - -const SEC_DESC *gums_get_sec_desc(const GUMS_OBJECT *obj) -{ - if (!obj) - return NULL; - - return obj->sec_desc; -} - -const DOM_SID *gums_get_object_sid(const GUMS_OBJECT *obj) -{ - if (!obj) - return NULL; - - return obj->sid; -} - -const char *gums_get_object_name(const GUMS_OBJECT *obj) -{ - if (!obj) - return NULL; - - return obj->name; -} - -const char *gums_get_object_description(const GUMS_OBJECT *obj) -{ - if (!obj) - return NULL; - - return obj->description; -} - -NTSTATUS gums_set_object_seq_num(GUMS_OBJECT *obj, uint32 seq_num) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - obj->seq_num = seq_num; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_object_version(GUMS_OBJECT *obj, uint32 version) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - obj->version = version; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_sec_desc(GUMS_OBJECT *obj, const SEC_DESC *sec_desc) -{ - if (!obj || !sec_desc) - return NT_STATUS_INVALID_PARAMETER; - - obj->sec_desc = dup_sec_desc(obj->mem_ctx, sec_desc); - if (!(obj->sec_desc)) return NT_STATUS_UNSUCCESSFUL; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_object_sid(GUMS_OBJECT *obj, const DOM_SID *sid) -{ - if (!obj || !sid) - return NT_STATUS_INVALID_PARAMETER; - - obj->sid = sid_dup_talloc(obj->mem_ctx, sid); - if (!(obj->sid)) return NT_STATUS_UNSUCCESSFUL; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_object_name(GUMS_OBJECT *obj, const char *name) -{ - if (!obj || !name) - return NT_STATUS_INVALID_PARAMETER; - - obj->name = (char *)talloc_strdup(obj->mem_ctx, name); - if (!(obj->name)) return NT_STATUS_UNSUCCESSFUL; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_object_description(GUMS_OBJECT *obj, const char *description) -{ - if (!obj || !description) - return NT_STATUS_INVALID_PARAMETER; - - obj->description = (char *)talloc_strdup(obj->mem_ctx, description); - if (!(obj->description)) return NT_STATUS_UNSUCCESSFUL; - return NT_STATUS_OK; -} - -/* -NTSTATUS gums_get_object_privileges(PRIVILEGE_SET **priv_set, const GUMS_OBJECT *obj) -{ - if (!priv_set) - return NT_STATUS_INVALID_PARAMETER; - - *priv_set = obj->priv_set; - return NT_STATUS_OK; -} -*/ - -uint32 gums_get_domain_next_rid(const GUMS_OBJECT *obj) -{ - if (obj->type != GUMS_OBJ_DOMAIN) - return -1; - - return obj->domain->next_rid; -} - -NTSTATUS gums_set_domain_next_rid(GUMS_OBJECT *obj, uint32 rid) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_DOMAIN) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->domain->next_rid = rid; - return NT_STATUS_OK; -} - -/* User specific functions */ - -const DOM_SID *gums_get_user_pri_group(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->group_sid; -} - -const DATA_BLOB gums_get_user_nt_pwd(const GUMS_OBJECT *obj) -{ - fstring p; - - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return data_blob(NULL, 0); - - pdb_sethexpwd(p, (unsigned char *)(obj->user->nt_pw.data), 0); - DEBUG(100, ("Reading NT Password=[%s]\n", p)); - - return obj->user->nt_pw; -} - -const DATA_BLOB gums_get_user_lm_pwd(const GUMS_OBJECT *obj) -{ - fstring p; - - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return data_blob(NULL, 0); - - pdb_sethexpwd(p, (unsigned char *)(obj->user->lm_pw.data), 0); - DEBUG(100, ("Reading LM Password=[%s]\n", p)); - - return obj->user->lm_pw; -} - -const char *gums_get_user_fullname(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->full_name; -} - -const char *gums_get_user_homedir(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->home_dir; -} - -const char *gums_get_user_dir_drive(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->dir_drive; -} - -const char *gums_get_user_profile_path(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->profile_path; -} - -const char *gums_get_user_logon_script(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->logon_script; -} - -const char *gums_get_user_workstations(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->workstations; -} - -const char *gums_get_user_unknown_str(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->unknown_str; -} - -const char *gums_get_user_munged_dial(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->munged_dial; -} - -NTTIME gums_get_user_logon_time(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) { - NTTIME null_time; - init_nt_time(&null_time); - return null_time; - } - - return obj->user->logon_time; -} - -NTTIME gums_get_user_logoff_time(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) { - NTTIME null_time; - init_nt_time(&null_time); - return null_time; - } - - return obj->user->logoff_time; -} - -NTTIME gums_get_user_kickoff_time(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) { - NTTIME null_time; - init_nt_time(&null_time); - return null_time; - } - - return obj->user->kickoff_time; -} - -NTTIME gums_get_user_pass_last_set_time(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) { - NTTIME null_time; - init_nt_time(&null_time); - return null_time; - } - - return obj->user->pass_last_set_time; -} - -NTTIME gums_get_user_pass_can_change_time(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) { - NTTIME null_time; - init_nt_time(&null_time); - return null_time; - } - - return obj->user->pass_can_change_time; -} - -NTTIME gums_get_user_pass_must_change_time(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) { - NTTIME null_time; - init_nt_time(&null_time); - return null_time; - } - - return obj->user->pass_must_change_time; -} - -uint16 gums_get_user_acct_ctrl(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->user->acct_ctrl; -} - -uint16 gums_get_user_logon_divs(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->user->logon_divs; -} - -uint32 gums_get_user_hours_len(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->user->hours_len; -} - -const uint8 *gums_get_user_hours(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return NULL; - - return obj->user->hours; -} - -uint32 gums_get_user_unknown_3(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->user->unknown_3; -} - -uint16 gums_get_user_bad_password_count(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->user->bad_password_count; -} - -uint16 gums_get_user_logon_count(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->user->logon_count; -} - -uint32 gums_get_user_unknown_6(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->user->unknown_6; -} - -NTSTATUS gums_set_user_pri_group(GUMS_OBJECT *obj, const DOM_SID *sid) -{ - if (!obj || !sid) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->group_sid = sid_dup_talloc(obj->mem_ctx, sid); - if (!(obj->user->group_sid)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_nt_pwd(GUMS_OBJECT *obj, const DATA_BLOB nt_pwd) -{ - fstring p; - unsigned char r[16]; - - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->nt_pw = data_blob_talloc(obj->mem_ctx, nt_pwd.data, nt_pwd.length); - - memcpy(r, nt_pwd.data, 16); - pdb_sethexpwd(p, r, 0); - DEBUG(100, ("Setting NT Password=[%s]\n", p)); - - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_lm_pwd(GUMS_OBJECT *obj, const DATA_BLOB lm_pwd) -{ - fstring p; - unsigned char r[16]; - - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->lm_pw = data_blob_talloc(obj->mem_ctx, lm_pwd.data, lm_pwd.length); - - memcpy(r, lm_pwd.data, 16); - pdb_sethexpwd(p, r, 0); - DEBUG(100, ("Setting LM Password=[%s]\n", p)); - - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_fullname(GUMS_OBJECT *obj, const char *fullname) -{ - if (!obj || !fullname) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->full_name = (char *)talloc_strdup(obj->mem_ctx, fullname); - if (!(obj->user->full_name)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_homedir(GUMS_OBJECT *obj, const char *homedir) -{ - if (!obj || !homedir) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->home_dir = (char *)talloc_strdup(obj->mem_ctx, homedir); - if (!(obj->user->home_dir)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_dir_drive(GUMS_OBJECT *obj, const char *dir_drive) -{ - if (!obj || !dir_drive) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->dir_drive = (char *)talloc_strdup(obj->mem_ctx, dir_drive); - if (!(obj->user->dir_drive)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_logon_script(GUMS_OBJECT *obj, const char *logon_script) -{ - if (!obj || !logon_script) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->logon_script = (char *)talloc_strdup(obj->mem_ctx, logon_script); - if (!(obj->user->logon_script)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_profile_path(GUMS_OBJECT *obj, const char *profile_path) -{ - if (!obj || !profile_path) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->profile_path = (char *)talloc_strdup(obj->mem_ctx, profile_path); - if (!(obj->user->profile_path)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_workstations(GUMS_OBJECT *obj, const char *workstations) -{ - if (!obj || !workstations) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->workstations = (char *)talloc_strdup(obj->mem_ctx, workstations); - if (!(obj->user->workstations)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_unknown_str(GUMS_OBJECT *obj, const char *unknown_str) -{ - if (!obj || !unknown_str) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->unknown_str = (char *)talloc_strdup(obj->mem_ctx, unknown_str); - if (!(obj->user->unknown_str)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_munged_dial(GUMS_OBJECT *obj, const char *munged_dial) -{ - if (!obj || !munged_dial) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->munged_dial = (char *)talloc_strdup(obj->mem_ctx, munged_dial); - if (!(obj->user->munged_dial)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_logon_time(GUMS_OBJECT *obj, NTTIME logon_time) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->logon_time = logon_time; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_logoff_time(GUMS_OBJECT *obj, NTTIME logoff_time) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->logoff_time = logoff_time; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_kickoff_time(GUMS_OBJECT *obj, NTTIME kickoff_time) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->kickoff_time = kickoff_time; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_pass_last_set_time(GUMS_OBJECT *obj, NTTIME pass_last_set_time) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->pass_last_set_time = pass_last_set_time; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_pass_can_change_time(GUMS_OBJECT *obj, NTTIME pass_can_change_time) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->pass_can_change_time = pass_can_change_time; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_pass_must_change_time(GUMS_OBJECT *obj, NTTIME pass_must_change_time) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->pass_must_change_time = pass_must_change_time; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_acct_ctrl(GUMS_OBJECT *obj, uint16 acct_ctrl) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->acct_ctrl = acct_ctrl; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_logon_divs(GUMS_OBJECT *obj, uint16 logon_divs) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->logon_divs = logon_divs; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_hours(GUMS_OBJECT *obj, uint32 hours_len, const uint8 *hours) -{ - if (!obj || !hours) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->hours_len = hours_len; - if (hours_len == 0) - DEBUG(10, ("gums_set_user_hours: Warning, hours_len is zero!\n")); - - obj->user->hours = (uint8 *)talloc(obj->mem_ctx, MAX_HOURS_LEN); - if (!(obj->user->hours)) - return NT_STATUS_NO_MEMORY; - if (hours_len) - memcpy(obj->user->hours, hours, hours_len); - - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_unknown_3(GUMS_OBJECT *obj, uint32 unknown_3) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->unknown_3 = unknown_3; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_bad_password_count(GUMS_OBJECT *obj, uint16 bad_password_count) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->bad_password_count = bad_password_count; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_logon_count(GUMS_OBJECT *obj, uint16 logon_count) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->logon_count = logon_count; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_user_unknown_6(GUMS_OBJECT *obj, uint32 unknown_6) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->user->unknown_6 = unknown_6; - return NT_STATUS_OK; -} - -/* Group specific functions */ - -const DOM_SID *gums_get_group_members(int *count, const GUMS_OBJECT *obj) -{ - if (!count || !obj || !(obj->type == GUMS_OBJ_GROUP || obj->type == GUMS_OBJ_ALIAS)) { - *count = -1; - return NULL; - } - - *count = obj->group->count; - return obj->group->members; -} - -NTSTATUS gums_set_group_members(GUMS_OBJECT *obj, uint32 count, DOM_SID *members) -{ - uint32 n; - - if (!obj || ((count > 0) && !members)) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_GROUP && - obj->type != GUMS_OBJ_ALIAS) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->group->count = count; - - if (count) { - obj->group->members = (DOM_SID *)talloc(obj->mem_ctx, count * sizeof(DOM_SID)); - if (!(obj->group->members)) { - return NT_STATUS_NO_MEMORY; - } - - - n = 0; - do { - sid_copy(&(obj->group->members[n]), &(members[n])); - n++; - } while (n < count); - } else { - obj->group->members = 0; - } - - return NT_STATUS_OK; -} - -/* Privilege specific functions */ - -const LUID_ATTR *gums_get_priv_luid_attr(const GUMS_PRIVILEGE *priv) -{ - if (!priv) { - return NULL; - } - - return priv->privilege; -} - -const DOM_SID *gums_get_priv_members(int *count, const GUMS_PRIVILEGE *priv) -{ - if (!count || !priv) { - *count = -1; - return NULL; - } - - *count = priv->count; - return priv->members; -} - -NTSTATUS gums_set_priv_luid_attr(GUMS_PRIVILEGE *priv, LUID_ATTR *luid_attr) -{ - if (!luid_attr || !priv) - return NT_STATUS_INVALID_PARAMETER; - - priv->privilege = (LUID_ATTR *)talloc_memdup(priv->mem_ctx, luid_attr, sizeof(LUID_ATTR)); - if (!(priv->privilege)) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -NTSTATUS gums_set_priv_members(GUMS_PRIVILEGE *priv, uint32 count, DOM_SID *members) -{ - uint32 n; - - if (!priv || !members || !members) - return NT_STATUS_INVALID_PARAMETER; - - priv->count = count; - priv->members = (DOM_SID *)talloc(priv->mem_ctx, count * sizeof(DOM_SID)); - if (!(priv->members)) - return NT_STATUS_NO_MEMORY; - - n = 0; - do { - sid_copy(&(priv->members[n]), &(members[n])); - n++; - } while (n < count); - - return NT_STATUS_OK; -} - -/* data_store set functions */ - -NTSTATUS gums_create_commit_set(GUMS_COMMIT_SET **com_set, DOM_SID *sid, uint32 type) -{ - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("commit_set"); - if (mem_ctx == NULL) - return NT_STATUS_NO_MEMORY; - - *com_set = (GUMS_COMMIT_SET *)talloc_zero(mem_ctx, sizeof(GUMS_COMMIT_SET)); - if (*com_set == NULL) { - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - (*com_set)->mem_ctx = mem_ctx; - (*com_set)->type = type; - sid_copy(&((*com_set)->sid), sid); - - return NT_STATUS_OK; -} - -NTSTATUS gums_cs_grow_data_set(GUMS_COMMIT_SET *com_set, int size) -{ - GUMS_DATA_SET *data_set; - - com_set->count = com_set->count + size; - if (com_set->count == size) { /* data set is empty*/ - data_set = (GUMS_DATA_SET *)talloc_zero(com_set->mem_ctx, sizeof(GUMS_DATA_SET)); - } else { - data_set = (GUMS_DATA_SET *)talloc_realloc(com_set->mem_ctx, com_set->data, sizeof(GUMS_DATA_SET) * com_set->count); - } - if (data_set == NULL) - return NT_STATUS_NO_MEMORY; - - com_set->data = data_set; - - return NT_STATUS_OK; -} - -NTSTATUS gums_cs_set_sec_desc(GUMS_COMMIT_SET *com_set, SEC_DESC *sec_desc) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - SEC_DESC *new_sec_desc; - - if (!com_set || !sec_desc) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1))) - return ret; - - data_set = &((com_set->data)[com_set->count - 1]); - - data_set->type = GUMS_SET_SEC_DESC; - new_sec_desc = dup_sec_desc(com_set->mem_ctx, sec_desc); - if (new_sec_desc == NULL) - return NT_STATUS_NO_MEMORY; - - (SEC_DESC *)(data_set->data) = new_sec_desc; - - return NT_STATUS_OK; -} - -/* -NTSTATUS gums_cs_add_privilege(GUMS_PRIV_COMMIT_SET *com_set, LUID_ATTR priv) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - LUID_ATTR *new_priv; - - if (!com_set) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1))) - return ret; - - data_set = ((com_set->data)[com_set->count - 1]); - - data_set->type = GUMS_ADD_PRIVILEGE; - if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(com_set->mem_ctx, &new_priv, priv))) - return ret; - - (SEC_DESC *)(data_set->data) = new_priv; - - return NT_STATUS_OK; -} - -NTSTATUS gums_cs_del_privilege(GUMS_PRIV_COMMIT_SET *com_set, LUID_ATTR priv) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - LUID_ATTR *new_priv; - - if (!com_set) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1))) - return ret; - - data_set = ((com_set->data)[com_set->count - 1]); - - data_set->type = GUMS_DEL_PRIVILEGE; - if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(com_set->mem_ctx, &new_priv, priv))) - return ret; - - (SEC_DESC *)(data_set->data) = new_priv; - - return NT_STATUS_OK; -} - -NTSTATUS gums_cs_set_privilege_set(GUMS_PRIV_COMMIT_SET *com_set, PRIVILEGE_SET *priv_set) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - PRIVILEGE_SET *new_priv_set; - - if (!com_set || !priv_set) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1))) - return ret; - - data_set = ((com_set->data)[com_set->count - 1]); - - data_set->type = GUMS_SET_PRIVILEGE; - if (!NT_STATUS_IS_OK(ret = init_priv_set_with_ctx(com_set->mem_ctx, &new_priv_set))) - return ret; - - if (!NT_STATUS_IS_OK(ret = dup_priv_set(new_priv_set, priv_set))) - return ret; - - (SEC_DESC *)(data_set->data) = new_priv_set; - - return NT_STATUS_OK; -} -*/ - -NTSTATUS gums_cs_set_string(GUMS_COMMIT_SET *com_set, uint32 type, char *str) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - char *new_str; - - if (!com_set || !str || type < GUMS_SET_NAME || type > GUMS_SET_MUNGED_DIAL) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1))) - return ret; - - data_set = &((com_set->data)[com_set->count - 1]); - - data_set->type = type; - new_str = talloc_strdup(com_set->mem_ctx, str); - if (new_str == NULL) - return NT_STATUS_NO_MEMORY; - - (char *)(data_set->data) = new_str; - - return NT_STATUS_OK; -} - -NTSTATUS gums_cs_set_name(GUMS_COMMIT_SET *com_set, char *name) -{ - return gums_cs_set_string(com_set, GUMS_SET_NAME, name); -} - -NTSTATUS gums_cs_set_description(GUMS_COMMIT_SET *com_set, char *desc) -{ - return gums_cs_set_string(com_set, GUMS_SET_DESCRIPTION, desc); -} - -NTSTATUS gums_cs_set_full_name(GUMS_COMMIT_SET *com_set, char *full_name) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, full_name); -} - -NTSTATUS gums_cs_set_home_directory(GUMS_COMMIT_SET *com_set, char *home_dir) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, home_dir); -} - -NTSTATUS gums_cs_set_drive(GUMS_COMMIT_SET *com_set, char *drive) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, drive); -} - -NTSTATUS gums_cs_set_logon_script(GUMS_COMMIT_SET *com_set, char *logon_script) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, logon_script); -} - -NTSTATUS gums_cs_set_profile_path(GUMS_COMMIT_SET *com_set, char *prof_path) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, prof_path); -} - -NTSTATUS gums_cs_set_workstations(GUMS_COMMIT_SET *com_set, char *wks) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, wks); -} - -NTSTATUS gums_cs_set_unknown_string(GUMS_COMMIT_SET *com_set, char *unkn_str) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, unkn_str); -} - -NTSTATUS gums_cs_set_munged_dial(GUMS_COMMIT_SET *com_set, char *munged_dial) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_string(com_set, GUMS_SET_NAME, munged_dial); -} - -NTSTATUS gums_cs_set_nttime(GUMS_COMMIT_SET *com_set, uint32 type, NTTIME *nttime) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - NTTIME *new_time; - - if (!com_set || !nttime || type < GUMS_SET_LOGON_TIME || type > GUMS_SET_PASS_MUST_CHANGE_TIME) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1))) - return ret; - - data_set = &((com_set->data)[com_set->count - 1]); - - data_set->type = type; - new_time = talloc(com_set->mem_ctx, sizeof(NTTIME)); - if (new_time == NULL) - return NT_STATUS_NO_MEMORY; - - new_time->low = nttime->low; - new_time->high = nttime->high; - (char *)(data_set->data) = new_time; - - return NT_STATUS_OK; -} - -NTSTATUS gums_cs_set_logon_time(GUMS_COMMIT_SET *com_set, NTTIME *logon_time) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, logon_time); -} - -NTSTATUS gums_cs_set_logoff_time(GUMS_COMMIT_SET *com_set, NTTIME *logoff_time) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_nttime(com_set, GUMS_SET_LOGOFF_TIME, logoff_time); -} - -NTSTATUS gums_cs_set_kickoff_time(GUMS_COMMIT_SET *com_set, NTTIME *kickoff_time) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_nttime(com_set, GUMS_SET_KICKOFF_TIME, kickoff_time); -} - -NTSTATUS gums_cs_set_pass_last_set_time(GUMS_COMMIT_SET *com_set, NTTIME *pls_time) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pls_time); -} - -NTSTATUS gums_cs_set_pass_can_change_time(GUMS_COMMIT_SET *com_set, NTTIME *pcc_time) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pcc_time); -} - -NTSTATUS gums_cs_set_pass_must_change_time(GUMS_COMMIT_SET *com_set, NTTIME *pmc_time) -{ - if (com_set->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pmc_time); -} - -NTSTATUS gums_cs_add_sids_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - DOM_SID **new_sids; - int i; - - if (!com_set || !sids) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1))) - return ret; - - data_set = &((com_set->data)[com_set->count - 1]); - - data_set->type = GUMS_ADD_SID_LIST; - new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count)); - if (new_sids == NULL) - return NT_STATUS_NO_MEMORY; - for (i = 0; i < count; i++) { - new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]); - if (new_sids[i] == NULL) - return NT_STATUS_NO_MEMORY; - } - - (SEC_DESC *)(data_set->data) = new_sids; - - return NT_STATUS_OK; -} - -NTSTATUS gums_cs_add_users_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count) -{ - if (!com_set || !sids) - return NT_STATUS_INVALID_PARAMETER; - if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_add_sids_to_group(com_set, sids, count); -} - -NTSTATUS gums_cs_add_groups_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count) -{ - if (!com_set || !sids) - return NT_STATUS_INVALID_PARAMETER; - if (com_set->type != GUMS_OBJ_ALIAS) - return NT_STATUS_INVALID_PARAMETER; - - return gums_cs_add_sids_to_group(com_set, sids, count); -} - -NTSTATUS gums_cs_del_sids_from_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - DOM_SID **new_sids; - int i; - - if (!com_set || !sids) - return NT_STATUS_INVALID_PARAMETER; - if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1))) - return ret; - - data_set = &((com_set->data)[com_set->count - 1]); - - data_set->type = GUMS_DEL_SID_LIST; - new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count)); - if (new_sids == NULL) - return NT_STATUS_NO_MEMORY; - for (i = 0; i < count; i++) { - new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]); - if (new_sids[i] == NULL) - return NT_STATUS_NO_MEMORY; - } - - (SEC_DESC *)(data_set->data) = new_sids; - - return NT_STATUS_OK; -} - -NTSTATUS gums_ds_set_sids_in_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count) -{ - NTSTATUS ret; - GUMS_DATA_SET *data_set; - DOM_SID **new_sids; - int i; - - if (!com_set || !sids) - return NT_STATUS_INVALID_PARAMETER; - if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1))) - return ret; - - data_set = &((com_set->data)[com_set->count - 1]); - - data_set->type = GUMS_SET_SID_LIST; - new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count)); - if (new_sids == NULL) - return NT_STATUS_NO_MEMORY; - for (i = 0; i < count; i++) { - new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]); - if (new_sids[i] == NULL) - return NT_STATUS_NO_MEMORY; - } - - (SEC_DESC *)(data_set->data) = new_sids; - - return NT_STATUS_OK; -} - -NTSTATUS gums_commit_data(GUMS_COMMIT_SET *set) -{ - NTSTATUS ret; - GUMS_FUNCTIONS *fns; - - if (!NT_STATUS_IS_OK(ret = get_gums_fns(&fns))) { - DEBUG(0, ("gums_commit_data: unable to get gums functions! backend uninitialized?\n")); - return ret; - } - return fns->set_object_values(&(set->sid), set->count, set->data); -} - -NTSTATUS gums_destroy_commit_set(GUMS_COMMIT_SET **com_set) -{ - talloc_destroy((*com_set)->mem_ctx); - *com_set = NULL; - - return NT_STATUS_OK; -} - diff --git a/source3/sam/gums_helper.c b/source3/sam/gums_helper.c deleted file mode 100644 index fcb9366cda..0000000000 --- a/source3/sam/gums_helper.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - Unix SMB/CIFS implementation. - GUMS backends helper functions - Copyright (C) Simo Sorce 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" - -extern DOM_SID global_sid_World; -extern DOM_SID global_sid_Builtin; -extern DOM_SID global_sid_Builtin_Administrators; -extern DOM_SID global_sid_Builtin_Power_Users; -extern DOM_SID global_sid_Builtin_Account_Operators; -extern DOM_SID global_sid_Builtin_Server_Operators; -extern DOM_SID global_sid_Builtin_Print_Operators; -extern DOM_SID global_sid_Builtin_Backup_Operators; -extern DOM_SID global_sid_Builtin_Replicator; -extern DOM_SID global_sid_Builtin_Users; -extern DOM_SID global_sid_Builtin_Guests; - - -/* defines */ - -#define ALLOC_CHECK(str, ptr, err, label) do { if ((ptr) == NULL) { DEBUG(0, ("%s: out of memory!\n", str)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0) -#define NTSTATUS_CHECK(err, label, str1, str2) do { if (NT_STATUS_IS_ERR(err)) { DEBUG(0, ("%s: %s\n", str1, str2)); } } while(0) - -/**************************************************************************** - Check if a user is a mapped group. - - This function will check if the group SID is mapped onto a - system managed gid or onto a winbind manged sid. - In the first case it will be threated like a mapped group - and the backend should take the member list with a getgrgid - and ignore any user that have been possibly set into the group - object. - - In the second case, the group is a fully SAM managed group - served back to the system through winbind. In this case the - members of a Local group are "unrolled" to cope with the fact - that unix cannot contain groups inside groups. - The backend MUST never call any getgr* / getpw* function or - loops with winbind may happen. - ****************************************************************************/ - -#if 0 -NTSTATUS is_mapped_group(BOOL *mapped, const DOM_SID *sid) -{ - NTSTATUS result; - gid_t id; - - /* look if mapping exist, do not make idmap alloc an uid if SID is not found */ - result = idmap_get_gid_from_sid(&id, sid, False); - if (NT_STATUS_IS_OK(result)) { - *mapped = gid_is_in_winbind_range(id); - } else { - *mapped = False; - } - - return result; -} -#endif - -#define ALIAS_DEFAULT_SACL_SA_RIGHTS 0x01050013 -#define ALIAS_DEFAULT_DACL_SA_RIGHTS \ - (READ_CONTROL_ACCESS | \ - SA_RIGHT_ALIAS_LOOKUP_INFO | \ - SA_RIGHT_ALIAS_GET_MEMBERS) /* 0x0002000c */ - -#define ALIAS_DEFAULT_SACL_SEC_ACE_FLAG (SEC_ACE_FLAG_FAILED_ACCESS | SEC_ACE_FLAG_SUCCESSFUL_ACCESS) /* 0xc0 */ - - -NTSTATUS create_builtin_alias_default_sec_desc(SEC_DESC **sec_desc, TALLOC_CTX *ctx) -{ - DOM_SID *world = &global_sid_World; - DOM_SID *admins = &global_sid_Builtin_Administrators; - SEC_ACCESS sa; - SEC_ACE sacl_ace; - SEC_ACE dacl_aces[2]; - SEC_ACL *sacl = NULL; - SEC_ACL *dacl = NULL; - size_t psize; - - init_sec_access(&sa, ALIAS_DEFAULT_SACL_SA_RIGHTS); - init_sec_ace(&sacl_ace, world, SEC_ACE_TYPE_SYSTEM_AUDIT, sa, ALIAS_DEFAULT_SACL_SEC_ACE_FLAG); - - sacl = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &sacl_ace); - if (!sacl) { - DEBUG(0, ("build_init_sec_desc: Failed to make SEC_ACL.\n")); - return NT_STATUS_NO_MEMORY; - } - - init_sec_access(&sa, ALIAS_DEFAULT_DACL_SA_RIGHTS); - init_sec_ace(&(dacl_aces[0]), world, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0); - init_sec_access(&sa, SA_RIGHT_ALIAS_ALL_ACCESS); - init_sec_ace(&(dacl_aces[1]), admins, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0); - - dacl = make_sec_acl(ctx, NT4_ACL_REVISION, 2, dacl_aces); - if (!sacl) { - DEBUG(0, ("build_init_sec_desc: Failed to make SEC_ACL.\n")); - return NT_STATUS_NO_MEMORY; - } - - *sec_desc = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, admins, admins, sacl, dacl, &psize); - if (!(*sec_desc)) { - DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n")); - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -NTSTATUS sec_desc_add_ace_to_dacl(SEC_DESC *sec_desc, TALLOC_CTX *ctx, DOM_SID *sid, uint32 mask) -{ - NTSTATUS result; - SEC_ACE *new_aces; - unsigned num_aces; - int i; - - num_aces = sec_desc->dacl->num_aces + 1; - result = sec_ace_add_sid(ctx, &new_aces, sec_desc->dacl->ace, &num_aces, sid, mask); - if (NT_STATUS_IS_OK(result)) { - sec_desc->dacl->ace = new_aces; - sec_desc->dacl->num_aces = num_aces; - sec_desc->dacl->size = SEC_ACL_HEADER_SIZE; - for (i = 0; i < num_aces; i++) { - sec_desc->dacl->size += sec_desc->dacl->ace[i].size; - } - } - return result; -} - -NTSTATUS gums_make_domain(DOM_SID *sid, const char *name, const char *description) -{ - NTSTATUS ret; - GUMS_OBJECT *go; - GUMS_FUNCTIONS *fns; - - if (!NT_STATUS_IS_OK(ret = get_gums_fns(&fns))) - return ret; - - if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, GUMS_OBJ_DOMAIN))) - return ret; - - ret = gums_set_object_sid(go, sid); - NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set sid!"); - - ret = gums_set_object_name(go, name); - NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set name!"); - - if (description) { - ret = gums_set_object_description(go, description); - NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set description!"); - } - - /* make security descriptor * / - ret = create_builtin_alias_default_sec_desc(&((*go).sec_desc), (*go).mem_ctx); - NTSTATUS_CHECK(ret, error, "gums_init_backend", "create_builtin_alias_default_sec_desc"); - */ - - ret = fns->set_object(go); - - gums_destroy_object(&go); - return ret; -} - -NTSTATUS gums_make_alias(DOM_SID *sid, const char *name, const char *description) -{ - NTSTATUS ret; - GUMS_OBJECT *go; - GUMS_FUNCTIONS *fns; - - if (!NT_STATUS_IS_OK(ret = get_gums_fns(&fns))) - return ret; - - if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, GUMS_OBJ_ALIAS))) - return ret; - - ret = gums_set_object_sid(go, sid); - NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set sid!"); - - ret = gums_set_object_name(go, name); - NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set name!"); - - if (description) { - ret = gums_set_object_description(go, description); - NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set description!"); - } - - /* make security descriptor * / - ret = create_builtin_alias_default_sec_desc(&((*go).sec_desc), (*go).mem_ctx); - NTSTATUS_CHECK(ret, error, "gums_init_backend", "create_builtin_alias_default_sec_desc"); - */ - - ret = fns->set_object(go); - - gums_destroy_object(&go); - return ret; -} - -NTSTATUS gums_init_domain(DOM_SID *sid, const char *name, const char * description) -{ - NTSTATUS ret; - - /* Add the weelknown Builtin Domain */ - if (!NT_STATUS_IS_OK(ret = gums_make_domain( - sid, - name, - description - ))) { - return ret; - } - - /* Add default users and groups */ - /* Administrator - Guest - Domain Administrators - Domain Users - Domain Guests - */ - - return ret; -} - -NTSTATUS gums_init_builtin_domain(void) -{ - NTSTATUS ret; - - generate_wellknown_sids(); - - /* Add the weelknown Builtin Domain */ - if (!NT_STATUS_IS_OK(ret = gums_make_domain( - &global_sid_Builtin, - "BUILTIN", - "Builtin Domain" - ))) { - return ret; - } - - /* Add the well known Builtin Local Groups */ - - /* Administrators */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Administrators, - "Administrators", - "Members can fully administer the computer/domain" - ))) { - return ret; - } - /* Administrator privilege set */ - /* From BDC join trace: - SeSecurityPrivilege, SeBackupPrivilege, SeRestorePrivilege, - SeSystemtimePrivilege, SeShutdownPrivilege, - SeRemoteShutdownPrivilege, SeTakeOwnershipPrivilege, - SeDebugPrivilege, SeSystemEnvironmentPrivilege, - SeSystemProfilePrivilege, SeProfileSingleProcessPrivilege, - SeIncreaseBasePriorityPrivilege, SeLocalDriverPrivilege, - SeCreatePagefilePrivilege, SeIncreaseQuotaPrivilege - */ - - /* Power Users */ - /* Domain Controllers Does NOT have Power Users (?) */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Power_Users, - "Power Users", - "Power Users" - ))) { - return ret; - } - - /* Power Users privilege set */ - /* (?) */ - - /* Account Operators */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Account_Operators, - "Account Operators", - "Members can administer domain user and group accounts" - ))) { - return ret; - } - - /* make privilege set */ - /* From BDC join trace: - SeShutdownPrivilege - */ - - /* Server Operators */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Server_Operators, - "Server Operators", - "Members can administer domain servers" - ))) { - return ret; - } - - /* make privilege set */ - /* From BDC join trace: - SeBackupPrivilege, SeRestorePrivilege, SeSystemtimePrivilege, - SeShutdownPrivilege, SeRemoteShutdownPrivilege - */ - - /* Print Operators */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Print_Operators, - "Print Operators", - "Members can administer domain printers" - ))) { - return ret; - } - - /* make privilege set */ - /* From BDC join trace: - SeShutdownPrivilege - */ - - /* Backup Operators */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Backup_Operators, - "Backup Operators", - "Members can bypass file security to backup files" - ))) { - return ret; - } - - /* make privilege set */ - /* From BDC join trace: - SeBackupPrivilege, SeRestorePrivilege, SeShutdownPrivilege - */ - - /* Replicator */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Replicator, - "Replicator", - "Supports file replication in a domain" - ))) { - return ret; - } - - /* make privilege set */ - /* From BDC join trace: - SeBackupPrivilege, SeRestorePrivilege, SeShutdownPrivilege - */ - - /* Users */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Users, - "Users", - "Ordinary users" - ))) { - return ret; - } - - /* Users specific ACEs * / - sec_desc_add_ace_to_dacl(go->sec_desc, go->mem_ctx, &global_sid_Builtin_Account_Operators, ALIAS_DEFAULT_DACL_SA_RIGHTS); - sec_desc_add_ace_to_dacl(go->sec_desc, go->mem_ctx, &global_sid_Builtin_Power_Users, ALIAS_DEFAULT_DACL_SA_RIGHTS); - */ - - /* Guests */ - if (!NT_STATUS_IS_OK(ret = gums_make_alias( - &global_sid_Builtin_Guests, - "Guests", - "Users granted guest access to the computer/domain" - ))) { - return ret; - } - - return ret; -} - diff --git a/source3/sam/gums_tdbsam2.c b/source3/sam/gums_tdbsam2.c deleted file mode 100644 index 7fb9a1a997..0000000000 --- a/source3/sam/gums_tdbsam2.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * tdbsam2 - sam backend - * Copyright (C) Simo Sorce 2002-2003 - * - * 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" -#include "tdbsam2_parse_info.h" - -#if 0 -static int gums_tdbsam2_debug_class = DBGC_ALL; -#endif -/* -#undef DBGC_CLASS -#define DBGC_CLASS gums_tdbsam2_debug_class -*/ - -#define TDBSAM_VERSION 20021215 -#define TDB_FILE_NAME "tdbsam2.tdb" -#define NAMEPREFIX "NAME_" -#define SIDPREFIX "SID_" -#define PRIVILEGEPREFIX "PRIV_" - -#define TDB_BASIC_OBJ_STRING "ddd" -#define TDB_FORMAT_STRING "dddB" -#define TDB_PRIV_FORMAT_STRING "ddB" - -#define TALLOC_CHECK(ptr, err, label) do { if ((ptr) == NULL) { DEBUG(0, ("%s: Out of memory!\n", FUNCTION_MACRO)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0) -#define SET_OR_FAIL(func, label) do { if (!NT_STATUS_IS_OK(func)) { DEBUG(0, ("%s: Setting gums object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0) - - - -struct tdbsam2_enum_objs { - uint32 type; - DOM_SID *dom_sid; - TDB_CONTEXT *db; - TDB_DATA key; - struct tdbsam2_enum_objs *next; -}; - -struct tdbsam2_private_data { - - const char *storage; - struct tdbsam2_enum_objs *teo_handlers; -}; - -static struct tdbsam2_private_data *ts2_privs; - -static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size) -{ - - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - TALLOC_CTX *mem_ctx; - int iret; - char *obj_data = NULL; - int data_size = 0; - int version, type, seqnum; - int len; - - mem_ctx = talloc_init("init_object_from_buffer"); - if (!mem_ctx) { - DEBUG(0, ("init_object_from_buffer: Out of memory!\n")); - return NT_STATUS_NO_MEMORY; - } - - len = tdb_unpack (buffer, size, TDB_FORMAT_STRING, - &version, - &type, - &seqnum, - &data_size, &obj_data); - - if (len == -1 || data_size <= 0) - goto done; - - /* version is checked inside this function so that backward - compatibility code can be called eventually. - This way we can easily handle database format upgrades */ - if (version != TDBSAM_VERSION) { - DEBUG(3,("init_object_from_buffer: Error, db object has wrong tdbsam version!\n")); - goto done; - } - - /* be sure the string is terminated before trying to parse it */ - if (obj_data[data_size - 1] != '\0') - obj_data[data_size - 1] = '\0'; - - *go = (GUMS_OBJECT *)talloc_zero(mem_ctx, sizeof(GUMS_OBJECT)); - TALLOC_CHECK(*go, ret, done); - - switch (type) { - - case GUMS_OBJ_DOMAIN: - iret = gen_parse(mem_ctx, pinfo_gums_domain, (char *)(*go), obj_data); - break; - - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - iret = gen_parse(mem_ctx, pinfo_gums_group, (char *)(*go), obj_data); - break; - - case GUMS_OBJ_NORMAL_USER: - iret = gen_parse(mem_ctx, pinfo_gums_user, (char *)(*go), obj_data); - break; - - default: - DEBUG(3,("init_object_from_buffer: Error, wrong object type number!\n")); - goto done; - } - - if (iret != 0) { - DEBUG(0, ("init_object_from_buffer: Fatal Error! Unable to parse object!\n")); - DEBUG(0, ("init_object_from_buffer: DB Corrupt ?")); - goto done; - } - - (*go)->mem_ctx = mem_ctx; - - ret = NT_STATUS_OK; -done: - SAFE_FREE(obj_data); - return ret; -} - -static NTSTATUS init_privilege_from_buffer(GUMS_PRIVILEGE **priv, char *buffer, int size) -{ - - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - TALLOC_CTX *mem_ctx; - int iret; - char *obj_data = NULL; - int data_size = 0; - int version, seqnum; - int len; - - mem_ctx = talloc_init("init_privilege_from_buffer"); - if (!mem_ctx) { - DEBUG(0, ("init_privilege_from_buffer: Out of memory!\n")); - return NT_STATUS_NO_MEMORY; - } - - len = tdb_unpack (buffer, size, TDB_PRIV_FORMAT_STRING, - &version, - &seqnum, - &data_size, &obj_data); - - if (len == -1 || data_size <= 0) - goto done; - - /* version is checked inside this function so that backward - compatibility code can be called eventually. - This way we can easily handle database format upgrades */ - if (version != TDBSAM_VERSION) { - DEBUG(3,("init_privilege_from_buffer: Error, db object has wrong tdbsam version!\n")); - goto done; - } - - /* be sure the string is terminated before trying to parse it */ - if (obj_data[data_size - 1] != '\0') - obj_data[data_size - 1] = '\0'; - - *priv = (GUMS_PRIVILEGE *)talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE)); - TALLOC_CHECK(*priv, ret, done); - - iret = gen_parse(mem_ctx, pinfo_gums_privilege, (char *)(*priv), obj_data); - - if (iret != 0) { - DEBUG(0, ("init_privilege_from_buffer: Fatal Error! Unable to parse object!\n")); - DEBUG(0, ("init_privilege_from_buffer: DB Corrupt ?")); - goto done; - } - - (*priv)->mem_ctx = mem_ctx; - - ret = NT_STATUS_OK; -done: - SAFE_FREE(obj_data); - return ret; -} - -static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_OBJECT *object) -{ - - NTSTATUS ret; - char *genbuf = NULL; - size_t buflen; - - if (!buffer) - return NT_STATUS_INVALID_PARAMETER; - - switch (gums_get_object_type(object)) { - - case GUMS_OBJ_DOMAIN: - genbuf = gen_dump(mem_ctx, pinfo_gums_domain, (char *)object, 0); - break; - - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - genbuf = gen_dump(mem_ctx, pinfo_gums_group, (char *)object, 0); - break; - - case GUMS_OBJ_NORMAL_USER: - genbuf = gen_dump(mem_ctx, pinfo_gums_user, (char *)object, 0); - break; - - default: - DEBUG(3,("init_buffer_from_object: Error, wrong object type number!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (genbuf == NULL) { - DEBUG(0, ("init_buffer_from_object: Fatal Error! Unable to dump object!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - buflen = tdb_pack(NULL, 0, TDB_FORMAT_STRING, - TDBSAM_VERSION, - object->type, - object->seq_num, - strlen(genbuf) + 1, genbuf); - - *buffer = talloc(mem_ctx, buflen); - TALLOC_CHECK(*buffer, ret, done); - - *len = tdb_pack(*buffer, buflen, TDB_FORMAT_STRING, - TDBSAM_VERSION, - object->type, - object->seq_num, - strlen(genbuf) + 1, genbuf); - - if (*len != buflen) { - DEBUG(0, ("init_buffer_from_object: something odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n", - buflen, *len)); - *buffer = NULL; - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - ret = NT_STATUS_OK; -done: - return ret; -} - -static NTSTATUS init_buffer_from_privilege(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_PRIVILEGE *priv) -{ - - NTSTATUS ret; - char *genbuf = NULL; - size_t buflen; - - if (!buffer || !len || !mem_ctx || !priv) - return NT_STATUS_INVALID_PARAMETER; - - genbuf = gen_dump(mem_ctx, pinfo_gums_privilege, (char *)priv, 0); - - if (genbuf == NULL) { - DEBUG(0, ("init_buffer_from_privilege: Fatal Error! Unable to dump object!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - buflen = tdb_pack(NULL, 0, TDB_PRIV_FORMAT_STRING, - TDBSAM_VERSION, - priv->seq_num, - strlen(genbuf) + 1, genbuf); - - *buffer = talloc(mem_ctx, buflen); - TALLOC_CHECK(*buffer, ret, done); - - *len = tdb_pack(*buffer, buflen, TDB_PRIV_FORMAT_STRING, - TDBSAM_VERSION, - priv->seq_num, - strlen(genbuf) + 1, genbuf); - - if (*len != buflen) { - DEBUG(0, ("init_buffer_from_privilege: something odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n", - buflen, *len)); - *buffer = NULL; - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - ret = NT_STATUS_OK; -done: - return ret; -} - -static NTSTATUS opentdb(TDB_CONTEXT **tdb, BOOL readonly) -{ - if (!tdb) - return NT_STATUS_INVALID_PARAMETER; - - *tdb = tdb_open_log(ts2_privs->storage, 0, TDB_DEFAULT, readonly?(O_RDONLY):(O_RDWR | O_CREAT), 0600); - if (!(*tdb)) - { - DEBUG(0, ("opentdb: Unable to open database (%s)!\n", ts2_privs->storage)); - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - -static NTSTATUS get_object_by_sid(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const DOM_SID *sid) -{ - NTSTATUS ret; - TDB_DATA data, key; - fstring keystr; - - if (!obj || !sid) - return NT_STATUS_INVALID_PARAMETER; - - slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid)); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(tdb, key); - if (!data.dptr) { - DEBUG(5, ("get_object_by_sid: Entry not found!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb))); - DEBUGADD(5, (" Key: %s\n", keystr)); - ret = NT_STATUS_NOT_FOUND; - goto done; - } - - if (!NT_STATUS_IS_OK(init_object_from_buffer(obj, data.dptr, data.dsize))) { - DEBUG(0, ("get_object_by_sid: Error fetching database, malformed entry!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - ret = NT_STATUS_OK; - -done: - SAFE_FREE(data.dptr); - return ret; -} - -static NTSTATUS make_full_object_name(TDB_CONTEXT *tdb, fstring objname, GUMS_OBJECT *object) -{ - NTSTATUS ret; - - objname[0] = '\0'; - - if (gums_get_object_type(object) == GUMS_OBJ_DOMAIN) { - - fstrcpy(objname, gums_get_object_name(object)); - - } else { - GUMS_OBJECT *domain_object; - DOM_SID domain_sid; - uint32 *discard_rid; - - sid_copy(&domain_sid, gums_get_object_sid(object)); - sid_split_rid(&domain_sid, discard_rid); - - if (!NT_STATUS_IS_OK(get_object_by_sid(tdb, - &domain_object, - &domain_sid))) { - - DEBUG(3, ("Object's domain not found!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - fstrcpy(objname, gums_get_object_name(domain_object)); - fstrcat(objname, "\\"); - fstrcat(objname, gums_get_object_name(object)); - } - - ret = NT_STATUS_OK; - -done: - return ret; -} - -/* name should be in DOMAIN\NAME format */ -static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char *fullname) -{ - - NTSTATUS ret = NT_STATUS_OK; - TDB_DATA data, key; - fstring keystr; - fstring objname; - DOM_SID sid; - fstring sidstr; - int sidstr_len; - - if (!obj || !fullname) - return NT_STATUS_INVALID_PARAMETER; - - /* Data is stored in all lower-case */ - fstrcpy(objname, fullname); - strlower_m(objname); - - slprintf(keystr, sizeof(keystr)-1, "%s%s", NAMEPREFIX, objname); - - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(tdb, key); - if (!data.dptr) { - DEBUG(5, ("get_object_by_name: Entry not found!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb))); - DEBUGADD(5, (" Key: %s\n", keystr)); - ret = NT_STATUS_NOT_FOUND; - goto done; - } - - fstrcpy(sidstr, data.dptr); - sidstr_len = data.dsize; - - SAFE_FREE(data.dptr); - - if (sidstr_len <= 0) { - DEBUG(5, ("get_object_by_name: Error unpacking database object!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!string_to_sid(&sid, sidstr)) { - DEBUG(5, ("get_object_by_name: Error invalid sid string found in database object!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - -done: - if (NT_STATUS_IS_OK(ret)) - return get_object_by_sid(tdb, obj, &sid); - return ret; -} - -/* Get object's sequence number */ - -static NTSTATUS get_object_seq_num(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int *seq_num) -{ - - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - TDB_DATA data, key; - fstring keystr; - fstring sidstr; - int version, type, seqnum; - - if (!object || !seq_num) - return NT_STATUS_INVALID_PARAMETER; - - fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object))); - slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sidstr); - - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(tdb, key); - if (!data.dptr) { - DEBUG(5, ("get_object_seq_num: Entry not found!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb))); - DEBUGADD(5, (" Key: %s\n", keystr)); - ret = NT_STATUS_NOT_FOUND; - goto done; - } - - if (tdb_unpack (data.dptr, data.dsize, TDB_BASIC_OBJ_STRING, &version, &type, &seqnum) == -1) - goto done; - - *seq_num = seqnum; - ret = NT_STATUS_OK; - -done: - SAFE_FREE(data.dptr); - return ret; -} - -/* store a gums object - * flag: TDB_REPLACE or TDB_MODIFY or TDB_INSERT - */ - -static NTSTATUS store_object(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int flag) -{ - NTSTATUS ret = NT_STATUS_OK; - TDB_DATA data, data2, key, key2; - TALLOC_CTX *mem_ctx; - fstring keystr; - fstring sidstr; - fstring namestr; - fstring objname; - int r; - - /* TODO: on object renaming/replacing this function should - * check name->sid record and delete the old one - */ - - mem_ctx = talloc_init("store_object"); - if (!mem_ctx) { - DEBUG(0, ("store_object: Out of memory!\n")); - return NT_STATUS_NO_MEMORY; - } - - make_full_object_name(tdb, objname, object); - - /* Data is stored in all lower-case */ - strlower_m(objname); - - if (flag == TDB_MODIFY) { - if (!NT_STATUS_IS_OK(ret = get_object_seq_num(tdb, object, &(object->seq_num)))) - goto done; - object->seq_num += 1; - } - - if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object))) - goto done; - - fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object))); - slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sidstr); - slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, objname); - - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - if ((r = tdb_store(tdb, key, data, flag)) != TDB_SUCCESS) { - DEBUG(0, ("store_object: Unable to modify TDBSAM!\n")); - DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb))); - DEBUGADD(0, (" occured while storing sid record (%s)\n", keystr)); - if (r == TDB_ERR_EXISTS) - ret = NT_STATUS_UNSUCCESSFUL; - else - ret = NT_STATUS_INTERNAL_DB_ERROR; - goto done; - } - - data2.dptr = sidstr; - data2.dsize = strlen(sidstr) + 1; - key2.dptr = namestr; - key2.dsize = strlen(namestr) + 1; - - if ((r = tdb_store(tdb, key2, data2, flag)) != TDB_SUCCESS) { - DEBUG(0, ("store_object: Unable to modify TDBSAM!\n")); - DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb))); - DEBUGADD(0, (" occured while storing name record (%s)\n", keystr)); - DEBUGADD(0, (" attempting rollback operation.\n")); - if ((tdb_delete(tdb, key)) != TDB_SUCCESS) { - DEBUG(0, ("store_object: Unable to rollback! Check database consitency!\n")); - } - if (r == TDB_ERR_EXISTS) - ret = NT_STATUS_UNSUCCESSFUL; - else - ret = NT_STATUS_INTERNAL_DB_ERROR; - goto done; - } - -/* TODO: update the general database counter */ -/* TODO: update this entry counter too */ - -done: - talloc_destroy(mem_ctx); - return ret; -} - -/* GUMM object functions */ - -static NTSTATUS tdbsam2_get_domain_sid(DOM_SID *sid, const char* name) -{ - - NTSTATUS ret; - TDB_CONTEXT *tdb; - GUMS_OBJECT *go; - fstring domname; - - if (!sid || !name) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) { - return ret; - } - - /* Data is stored in all lower-case */ - fstrcpy(domname, name); - strlower_m(domname); - - if (!NT_STATUS_IS_OK(ret = get_object_by_name(tdb, &go, domname))) { - go = NULL; - DEBUG(0, ("tdbsam2_get_domain_sid: Error fetching database!\n")); - goto done; - } - - if (gums_get_object_type(go) != GUMS_OBJ_DOMAIN) { - DEBUG(5, ("tdbsam2_get_domain_sid: Requested object is not a domain!\n")); - ret = NT_STATUS_OBJECT_TYPE_MISMATCH; - goto done; - } - - sid_copy(sid, gums_get_object_sid(go)); - - ret = NT_STATUS_OK; - -done: - if (go) - gums_destroy_object(&go); - tdb_close(tdb); - return ret; -} - -static NTSTATUS get_next_sid(TDB_CONTEXT *tdb, DOM_SID *sid) -{ - NTSTATUS ret; - GUMS_OBJECT *go; - DOM_SID dom_sid; - TDB_DATA dom_sid_key; - fstring dom_sid_str; - uint32 new_rid; - - /* Find the domain SID */ - if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, global_myname()))) { - DEBUG(0, ("get_next_sid: cannot found the domain sid!!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - /* Lock the domain record */ - sid_to_string(dom_sid_str, &dom_sid); - dom_sid_key.dptr = dom_sid_str; - dom_sid_key.dsize = strlen(dom_sid_key.dptr) + 1; - - if(tdb_chainlock(tdb, dom_sid_key) != 0) { - DEBUG(0, ("get_next_sid: unable to lock domain record!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - /* Get the domain object */ - ret = get_object_by_sid(tdb, &go, &dom_sid); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("get_next_sid: unable to get root Domain object!\n")); - ret = NT_STATUS_INTERNAL_DB_ERROR; - goto done; - } - - new_rid = gums_get_domain_next_rid(go); - - /* Increment the RID Counter */ - gums_set_domain_next_rid(go, new_rid+1); - - /* Store back Domain object */ - ret = store_object(tdb, go, TDB_MODIFY); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("get_next_sid: unable to update root Domain object!\n")); - ret = NT_STATUS_INTERNAL_DB_ERROR; - goto done; - } - - /* Build the Domain SID to return */ - sid_copy(sid, &dom_sid); - - if (!sid_append_rid(sid, new_rid)) { - DEBUG(0, ("get_next_sid: unable to build new SID !?!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - ret = NT_STATUS_OK; - -done: - /* Unlock the Domain object */ - tdb_chainunlock(tdb, dom_sid_key); - - return ret; -} - -/* TODO */ - NTSTATUS (*get_sequence_number) (void); - - -extern DOM_SID global_sid_NULL; - -static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj_type) -{ - - NTSTATUS ret = NT_STATUS_OK; - TDB_CONTEXT *tdb; - GUMS_OBJECT *go; - NTTIME null_time; - DATA_BLOB pw; - const char *defpw = "NOPASSWORDXXXXXX"; - uint8 defhours[21] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}; - - if (!name) { - DEBUG(0, ("tdbsam2_new_object: no NULL pointers are accepted here!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) { - return ret; - } - - if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, obj_type))) { - go = NULL; - goto done; - } - - if (obj_type == GUMS_OBJ_DOMAIN) { - sid_copy(sid, get_global_sam_sid()); - } else { - if (!NT_STATUS_IS_OK(ret = get_next_sid(tdb, sid))) - goto done; - } - - gums_set_object_sid(go, sid); - gums_set_object_name(go, name); - gums_set_object_seq_num(go, 1); - - /*obj.domain->sec_desc*/ - - switch (obj_type) { - case GUMS_OBJ_NORMAL_USER: - - init_nt_time(&null_time); - - gums_set_user_logon_time(go, null_time); - gums_set_user_logoff_time(go, null_time); - gums_set_user_kickoff_time(go, null_time); - gums_set_user_pass_last_set_time(go, null_time); - gums_set_user_pass_can_change_time(go, null_time); - gums_set_user_pass_must_change_time(go, null_time); - - pw = data_blob(defpw, NT_HASH_LEN); - gums_set_user_nt_pwd(go, pw); - gums_set_user_lm_pwd(go, pw); - data_blob_free(&pw); - - gums_set_user_logon_divs(go, 168); - gums_set_user_hours(go, 21, defhours); - - gums_set_user_bad_password_count(go, 0); - gums_set_user_logon_count(go, 0); - gums_set_user_unknown_6(go, 0x000004ec); - break; - - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - - break; - - case GUMS_OBJ_DOMAIN: - - gums_set_domain_next_rid(go, 0x3e9); - - break; - - default: - ret = NT_STATUS_OBJECT_TYPE_MISMATCH; - goto done; - } - - ret = store_object(tdb, go, TDB_INSERT); - -done: - if (go) - gums_destroy_object(&go); - tdb_close(tdb); - return ret; -} - -/* TODO: handle privileges objects */ - -static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid) -{ - /* TODO: need to address privilege deletion */ - NTSTATUS ret = NT_STATUS_OK; - TDB_CONTEXT *tdb; - GUMS_OBJECT *go; - TDB_DATA data, key; - fstring keystr; - - if (!sid) { - DEBUG(0, ("tdbsam2_delete_object: no NULL pointers are accepted here!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) { - return ret; - } - - slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(sid)); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(tdb, key); - if (!data.dptr) { - DEBUG(5, ("tdbsam2_delete_object: Error fetching database, SID entry not found!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb))); - DEBUGADD(5, (" Key: %s\n", keystr)); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (tdb_delete(tdb, key) != TDB_SUCCESS) { - DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb))); - DEBUGADD(5, (" Key: %s\n", keystr)); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(init_object_from_buffer(&go, data.dptr, data.dsize))) { - DEBUG(0, ("tdbsam2_delete_object: Error fetching database, malformed entry!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go)); - - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - if (tdb_delete(tdb, key) != TDB_SUCCESS) { - DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb))); - DEBUGADD(5, (" Key: %s\n", keystr)); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - -/* TODO: update the general database counter */ - -done: - gums_destroy_object(&go); - SAFE_FREE(data.dptr); - return ret; -} - -static NTSTATUS tdbsam2_get_object_from_sid(GUMS_OBJECT **object, const DOM_SID *sid, const int obj_type) -{ - NTSTATUS ret; - TDB_CONTEXT *tdb; - - if (!object || !sid) { - DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) { - return ret; - } - - ret = get_object_by_sid(tdb, object, sid); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("tdbsam2_get_object_from_sid: %s\n", nt_errstr(ret))); - goto error; - } - if (obj_type && gums_get_object_type(*object) != obj_type) { - DEBUG(0, ("tdbsam2_get_object_from_sid: the object is not of the rerquested type!\n")); - goto error; - } - - tdb_close(tdb); - return NT_STATUS_OK; - -error: - gums_destroy_object(object); - tdb_close(tdb); - return ret; -} - -static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *domain, const char *name, const int obj_type) -{ - NTSTATUS ret; - TDB_CONTEXT *tdb; - fstring objname; - - if (!object || !name) { - DEBUG(0, ("tdbsam2_get_object_from_name: no NULL pointers are accepted here!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) { - return ret; - } - - if (obj_type == GUMS_OBJ_DOMAIN) { - fstrcpy(objname, name); - } else { - if (!domain) { - domain = global_myname(); - } - fstrcpy(objname, domain); - fstrcat(objname, "\\"); - fstrcat(objname, name); - } - - *object = NULL; - ret = get_object_by_name(tdb, object, name); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("tdbsam2_get_object_from_name: %s\n", nt_errstr(ret))); - goto error; - } - if (obj_type && gums_get_object_type(*object) != obj_type) { - DEBUG(0, ("tdbsam2_get_object_from_name: the object is not of the rerquested type!\n")); - goto error; - } - - tdb_close(tdb); - return NT_STATUS_OK; - -error: - gums_destroy_object(object); - tdb_close(tdb); - return ret; -} - - /* This function is used to get the list of all objects changed since base_time, it is - used to support PDC<->BDC synchronization */ - NTSTATUS (*get_updated_objects) (GUMS_OBJECT **objects, const NTTIME base_time); - -static NTSTATUS tdbsam2_enumerate_objects_start(void **handle, const DOM_SID *sid, const int obj_type) -{ - struct tdbsam2_enum_objs *teo, *t; - - teo = (struct tdbsam2_enum_objs *)malloc(sizeof(struct tdbsam2_enum_objs)); - if (!teo) { - DEBUG(0, ("tdbsam2_enumerate_objects_start: Out of Memory!\n")); - return NT_STATUS_NO_MEMORY; - } - memset(teo, 0, sizeof(struct tdbsam2_enum_objs)); - - teo->type = obj_type; - if (sid) { - teo->dom_sid = (DOM_SID *)malloc(sizeof(DOM_SID)); - if (!teo->dom_sid) { - DEBUG(0, ("tdbsam2_enumerate_objects_start: Out of Memory!\n")); - return NT_STATUS_NO_MEMORY; - } - sid_copy(teo->dom_sid, sid); - } - - if (!NT_STATUS_IS_OK(opentdb(&(teo->db), True))) - { - DEBUG(0, ("tdbsam2_enumerate_objects_start: Unable to open database (%s)!\n", ts2_privs->storage)); - SAFE_FREE(teo); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!ts2_privs->teo_handlers) { - ts2_privs->teo_handlers = teo; - } else { - t = ts2_privs->teo_handlers; - while (t->next) { - t = t->next; - } - t->next = teo; - } - - *handle = teo; - - teo->key = tdb_firstkey(teo->db); - - return NT_STATUS_OK; -} - -static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *handle) -{ - NTSTATUS ret; - TDB_DATA data; - struct tdbsam2_enum_objs *teo; - const char *prefix = SIDPREFIX; - const int preflen = strlen(prefix); - fstring dom_sid_str; - int dom_sid_str_len = 0; - - if (!object || !handle) { - DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - teo = (struct tdbsam2_enum_objs *)handle; - - if (teo->dom_sid) { - sid_to_string(dom_sid_str, teo->dom_sid); - dom_sid_str_len = strlen(dom_sid_str); - } - - while ((teo->key.dptr != NULL)) { - int len, version, type, size, seqnum; - char *ptr; - - if (strncmp(teo->key.dptr, prefix, preflen)) { - teo->key = tdb_nextkey(teo->db, teo->key); - continue; - } - - if (dom_sid_str_len != 0) { - if (strncmp(&(teo->key.dptr[preflen]), dom_sid_str, dom_sid_str_len)) { - teo->key = tdb_nextkey(teo->db, teo->key); - continue; - } - } - - data = tdb_fetch(teo->db, teo->key); - if (!data.dptr) { - DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error fetching database, SID entry not found!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(teo->db))); - DEBUGADD(5, (" Key: %s\n", teo->key.dptr)); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - len = tdb_unpack (data.dptr, data.dsize, TDB_FORMAT_STRING, - &version, - &type, - &seqnum, - &size, &ptr); - - if (len == -1) { - DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error unable to unpack data!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - SAFE_FREE(ptr); - - if (teo->type && type != teo->type) { - SAFE_FREE(data.dptr); - data.dsize = 0; - teo->key = tdb_nextkey(teo->db, teo->key); - continue; - } - - break; - } - - if (teo->key.dptr == NULL) { /* no more objs */ - ret = NT_STATUS_NO_MORE_ENTRIES; - goto done; - } - - if (!NT_STATUS_IS_OK(ret = init_object_from_buffer(object, data.dptr, data.dsize))) { - SAFE_FREE(data.dptr); - DEBUG(0, ("tdbsam2_enumerate_objects_get_next: Error fetching database, malformed entry!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - SAFE_FREE(data.dptr); - - /* prepare next run */ - teo->key = tdb_nextkey(teo->db, teo->key); - -done: - return ret; -} - -static NTSTATUS tdbsam2_enumerate_objects_stop(void *handle) -{ - struct tdbsam2_enum_objs *teo, *t, *p; - - teo = (struct tdbsam2_enum_objs *)handle; - - if (ts2_privs->teo_handlers == teo) { - ts2_privs->teo_handlers = teo->next; - } else { - t = ts2_privs->teo_handlers; - while (t != teo) { - p = t; - t = t->next; - if (t == NULL) { - DEBUG(0, ("tdbsam2_enumerate_objects_stop: Error, handle not found!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - } - p = t->next; - } - - tdb_close(teo->db); - SAFE_FREE(teo->dom_sid); - SAFE_FREE(teo); - - return NT_STATUS_OK; -} - -static NTSTATUS tdbsam2_set_object(GUMS_OBJECT *go) -{ - NTSTATUS ret; - TDB_CONTEXT *tdb; - - if (!go) - return NT_STATUS_INVALID_PARAMETER; - - if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) { - return ret; - } - - ret = store_object(tdb, go, TDB_REPLACE); - - tdb_close(tdb); - return ret; -} - -#if 0 - /* set object values function */ -static NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set); - - /* Group related functions */ -static NTSTATUS (*add_memberss_to_group) (const DOM_SID *group, const DOM_SID **members); - NTSTATUS (*delete_members_from_group) (const DOM_SID *group, const DOM_SID **members); -static NTSTATUS (*enumerate_group_members) (DOM_SID **members, const DOM_SID *sid, const int type); - -static NTSTATUS (*get_sid_groups) (DOM_SID **groups, const DOM_SID *sid); - -static NTSTATUS (*lock_sid) (const DOM_SID *sid); -static NTSTATUS (*unlock_sid) (const DOM_SID *sid); - - /* privileges related functions */ - -static NTSTATUS (*get_privilege) (GUMS_OBJECT **object, const char *name); -static NTSTATUS (*add_members_to_privilege) (const char *name, const DOM_SID **members); -static NTSTATUS (*delete_members_from_privilege) (const char *name, const DOM_SID **members); -static NTSTATUS (*enumerate_privilege_members) (const char *name, DOM_SID **members); -static NTSTATUS (*get_sid_privileges) (const DOM_SID *sid, const char **privs); - - /* warning!: set_privilege will overwrite a prior existing privilege if such exist */ -static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv); -#endif - -static void free_tdbsam2_private_data(void **vp) -{ - struct tdbsam2_private_data **tdb_privs = (struct tdbsam2_private_data **)vp; - while (ts2_privs->teo_handlers) - tdbsam2_enumerate_objects_stop(ts2_privs->teo_handlers); - *tdb_privs = NULL; - /* No need to free any further, as it is talloc()ed */ -} - -static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage) -{ - NTSTATUS ret; - TDB_CONTEXT *tdb; - DOM_SID dom_sid; - - fns->name = talloc_strdup(fns->mem_ctx, "tdbsam2"); - - fns->get_domain_sid = tdbsam2_get_domain_sid; - /* fns->get_sequence_number = tdbsam2_get_sequence_number; */ - fns->new_object = tdbsam2_new_object; - fns->delete_object = tdbsam2_delete_object; - fns->get_object_from_sid = tdbsam2_get_object_from_sid; - fns->get_object_from_name = tdbsam2_get_object_from_name; - /* fns->get_updated_objects = tdbsam2_get_updated_objects; */ - fns->enumerate_objects_start = tdbsam2_enumerate_objects_start; - fns->enumerate_objects_get_next = tdbsam2_enumerate_objects_get_next; - fns->enumerate_objects_stop = tdbsam2_enumerate_objects_stop; - fns->set_object = tdbsam2_set_object; - /* fns->set_object_values = tdbsam2_set_object_values; - fns->add_members_to_group = tdbsam2_add_members_to_group; - fns->delete_members_from_group = tdbsam2_delete_members_from_group; - fns->enumerate_group_members = tdbsam2_enumerate_group_members; - fns->get_sid_groups = tdbsam2_get_sid_groups; - fns->lock_sid = tdbsam2_lock_sid; - fns->unlock_sid = tdbsam2_unlock_sid; - fns->get_privilege = tdbsam2_get_privilege; - fns->add_members_to_privilege = tdbsam2_add_members_to_privilege; - fns->delete_members_from_privilege = tdbsam2_delete_members_from_privilege; - fns->enumerate_privilege_members = tdbsam2_enumerate_privilege_members; - fns->get_sid_privileges = tdbsam2_get_sid_privileges; - fns->set_privilege = tdbsam2_set_privilege; */ - - ts2_privs = talloc_zero(fns->mem_ctx, sizeof(struct tdbsam2_private_data)); - if (!ts2_privs) { - DEBUG(0, ("talloc() failed for tdbsam2 private_data!\n")); - return NT_STATUS_NO_MEMORY; - } - - if (storage) { - ts2_privs->storage = talloc_strdup(fns->mem_ctx, storage); - } else { - pstring tdbfile; - get_private_directory(tdbfile); - pstrcat(tdbfile, "/"); - pstrcat(tdbfile, TDB_FILE_NAME); - ts2_privs->storage = talloc_strdup(fns->mem_ctx, tdbfile); - } - - /* check tdb exist (or create it) */ - - /* Find the domain SID */ - if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, global_myname()))) { - /* db file does not exist or it is not inited */ - /* make the tdb file */ - if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) { - return ret; - } - tdb_close(tdb); - - if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, "BUILTIN"))) { - gums_init_builtin_domain(); - } - - gums_init_domain(get_global_sam_sid(), global_myname(), "The Domain"); - } - - fns->private_data = &ts2_privs; - fns->free_private_data = free_tdbsam2_private_data; - - return NT_STATUS_OK; -} - -NTSTATUS gums_tdbsam2_init(void) -{ - /* - if ((gums_tdbsam2_debug_class = debug_add_class("gums_tdbsam2")) == -1) { - DEBUG(0, ("gums_tdbsam2: unable to register my own debug class! going on ...\n")); - gums_tdbsam2_debug_class = DBGC_ALL; - } - */ - return gums_register_module(GUMS_INTERFACE_VERSION, "tdbsam2", init_tdbsam2); -} diff --git a/source3/sam/interface.c b/source3/sam/interface.c deleted file mode 100644 index 51ae561999..0000000000 --- a/source3/sam/interface.c +++ /dev/null @@ -1,1338 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Jelmer Vernooij 2002 - Copyright (C) Stefan (metze) Metzmacher 2002 - Copyright (C) Kai Krüger 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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_SAM - -extern DOM_SID global_sid_Builtin; - -/** List of various built-in sam modules */ - -const struct sam_init_function_entry builtin_sam_init_functions[] = { - { "plugin", sam_init_plugin }, -#ifdef HAVE_LDAP - { "ads", sam_init_ads }, -#endif - { "skel", sam_init_skel }, - { NULL, NULL} -}; - - -static NTSTATUS sam_get_methods_by_sid(const SAM_CONTEXT *context, SAM_METHODS **sam_method, const DOM_SID *domainsid) -{ - SAM_METHODS *tmp_methods; - - DEBUG(5,("sam_get_methods_by_sid: %d\n", __LINE__)); - - /* invalid sam_context specified */ - SAM_ASSERT(context && context->methods); - - tmp_methods = context->methods; - - while (tmp_methods) { - if (sid_equal(domainsid, &(tmp_methods->domain_sid))) - { - (*sam_method) = tmp_methods; - return NT_STATUS_OK; - } - tmp_methods = tmp_methods->next; - } - - DEBUG(3,("sam_get_methods_by_sid: There is no backend specified for domain %s\n", sid_string_static(domainsid))); - - return NT_STATUS_NO_SUCH_DOMAIN; -} - -static NTSTATUS sam_get_methods_by_name(const SAM_CONTEXT *context, SAM_METHODS **sam_method, const char *domainname) -{ - SAM_METHODS *tmp_methods; - - DEBUG(5,("sam_get_methods_by_name: %d\n", __LINE__)); - - /* invalid sam_context specified */ - SAM_ASSERT(context && context->methods); - - tmp_methods = context->methods; - - while (tmp_methods) { - if (strequal(domainname, tmp_methods->domain_name)) - { - (*sam_method) = tmp_methods; - return NT_STATUS_OK; - } - tmp_methods = tmp_methods->next; - } - - DEBUG(3,("sam_get_methods_by_sid: There is no backend specified for domain %s\n", domainname)); - - return NT_STATUS_NO_SUCH_DOMAIN; -} - -static NTSTATUS make_sam_methods(TALLOC_CTX *mem_ctx, SAM_METHODS **methods) -{ - *methods = talloc(mem_ctx, sizeof(SAM_METHODS)); - - if (!*methods) { - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(*methods); - - return NT_STATUS_OK; -} - -/****************************************************************** - Free and cleanup a sam context, any associated data and anything - that the attached modules might have associated. - *******************************************************************/ - -void free_sam_context(SAM_CONTEXT **context) -{ - SAM_METHODS *sam_selected = (*context)->methods; - - while (sam_selected) { - if (sam_selected->free_private_data) { - sam_selected->free_private_data(&(sam_selected->private_data)); - } - sam_selected = sam_selected->next; - } - - talloc_destroy((*context)->mem_ctx); - *context = NULL; -} - -/****************************************************************** - Make a backend_entry from scratch - *******************************************************************/ - -static NTSTATUS make_backend_entry(SAM_BACKEND_ENTRY *backend_entry, char *sam_backend_string) -{ - char *tmp = NULL; - char *tmp_string = sam_backend_string; - - DEBUG(5,("make_backend_entry: %d\n", __LINE__)); - - SAM_ASSERT(sam_backend_string && backend_entry); - - backend_entry->module_name = sam_backend_string; - - DEBUG(5,("makeing backend_entry for %s\n", backend_entry->module_name)); - - if ((tmp = strrchr(tmp_string, '|')) != NULL) { - DEBUGADD(20,("a domain name has been specified\n")); - *tmp = 0; - backend_entry->domain_name = smb_xstrdup(tmp + 1); - tmp_string = tmp + 1; - } - - if ((tmp = strchr(tmp_string, ':')) != NULL) { - DEBUG(20,("options for the backend have been specified\n")); - *tmp = 0; - backend_entry->module_params = smb_xstrdup(tmp + 1); - tmp_string = tmp + 1; - } - - if (backend_entry->domain_name == NULL) { - DEBUG(10,("make_backend_entry: no domain was specified for sam module %s. Using default domain %s\n", - backend_entry->module_name, lp_workgroup())); - backend_entry->domain_name = smb_xstrdup(lp_workgroup()); - } - - if ((backend_entry->domain_sid = (DOM_SID *)malloc(sizeof(DOM_SID))) == NULL) { - DEBUG(0,("make_backend_entry: failed to malloc domain_sid\n")); - return NT_STATUS_NO_MEMORY; - } - - DEBUG(10,("looking up sid for domain %s\n", backend_entry->domain_name)); - - if (!secrets_fetch_domain_sid(backend_entry->domain_name, backend_entry->domain_sid)) { - DEBUG(2,("make_backend_entry: There is no SID stored for domain %s. Creating a new one.\n", - backend_entry->domain_name)); - DEBUG(0, ("FIXME in %s:%d\n", __FILE__, __LINE__)); - ZERO_STRUCTP(backend_entry->domain_sid); - } - - DEBUG(5,("make_backend_entry: module name: %s, module parameters: %s, domain name: %s, domain sid: %s\n", - backend_entry->module_name, backend_entry->module_params, backend_entry->domain_name, sid_string_static(backend_entry->domain_sid))); - - return NT_STATUS_OK; -} - -/****************************************************************** - create sam_methods struct based on sam_backend_entry - *****************************************************************/ - -static NTSTATUS make_sam_methods_backend_entry(SAM_CONTEXT *context, SAM_METHODS **methods_ptr, SAM_BACKEND_ENTRY *backend_entry) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - SAM_METHODS *methods; - int i; - - DEBUG(5,("make_sam_methods_backend_entry: %d\n", __LINE__)); - - if (!NT_STATUS_IS_OK(nt_status = make_sam_methods(context->mem_ctx, methods_ptr))) { - return nt_status; - } - - methods = *methods_ptr; - methods->backendname = talloc_strdup(context->mem_ctx, backend_entry->module_name); - methods->domain_name = talloc_strdup(context->mem_ctx, backend_entry->domain_name); - sid_copy(&methods->domain_sid, backend_entry->domain_sid); - methods->parent = context; - - DEBUG(5,("Attempting to find sam backend %s\n", backend_entry->module_name)); - for (i = 0; builtin_sam_init_functions[i].module_name; i++) - { - if (strequal(builtin_sam_init_functions[i].module_name, backend_entry->module_name)) - { - DEBUG(5,("Found sam backend %s (at pos %d)\n", backend_entry->module_name, i)); - DEBUGADD(5,("initialising it with options=%s for domain %s\n", backend_entry->module_params, sid_string_static(backend_entry->domain_sid))); - nt_status = builtin_sam_init_functions[i].init(methods, backend_entry->module_params); - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(5,("sam backend %s has a valid init\n", backend_entry->module_name)); - } else { - DEBUG(2,("sam backend %s did not correctly init (error was %s)\n", - backend_entry->module_name, nt_errstr(nt_status))); - } - return nt_status; - } - } - - DEBUG(2,("could not find backend %s\n", backend_entry->module_name)); - - return NT_STATUS_INVALID_PARAMETER; -} - -static NTSTATUS sam_context_check_default_backends(SAM_CONTEXT *context) -{ - SAM_BACKEND_ENTRY entry; - DOM_SID *global_sam_sid = get_global_sam_sid(); /* lp_workgroup doesn't play nicely with multiple domains */ - SAM_METHODS *methods, *tmpmethods; - NTSTATUS ntstatus; - - DEBUG(5,("sam_context_check_default_backends: %d\n", __LINE__)); - - /* Make sure domain lp_workgroup() is available */ - - ntstatus = sam_get_methods_by_sid(context, &methods, &global_sid_Builtin); - - if (NT_STATUS_EQUAL(ntstatus, NT_STATUS_NO_SUCH_DOMAIN)) { - DEBUG(4,("There was no backend specified for domain %s(%s); using %s\n", - lp_workgroup(), sid_string_static(global_sam_sid), SAM_DEFAULT_BACKEND)); - - SAM_ASSERT(global_sam_sid); - - entry.module_name = SAM_DEFAULT_BACKEND; - entry.module_params = NULL; - entry.domain_name = lp_workgroup(); - entry.domain_sid = (DOM_SID *)malloc(sizeof(DOM_SID)); - sid_copy(entry.domain_sid, global_sam_sid); - - if (!NT_STATUS_IS_OK(ntstatus = make_sam_methods_backend_entry(context, &methods, &entry))) { - DEBUG(4,("make_sam_methods_backend_entry failed\n")); - return ntstatus; - } - - DLIST_ADD_END(context->methods, methods, tmpmethods); - - } else if (!NT_STATUS_IS_OK(ntstatus)) { - DEBUG(2, ("sam_get_methods_by_sid failed for %s\n", lp_workgroup())); - return ntstatus; - } - - /* Make sure the BUILTIN domain is available */ - - ntstatus = sam_get_methods_by_sid(context, &methods, global_sam_sid); - - if (NT_STATUS_EQUAL(ntstatus, NT_STATUS_NO_SUCH_DOMAIN)) { - DEBUG(4,("There was no backend specified for domain BUILTIN; using %s\n", - SAM_DEFAULT_BACKEND)); - entry.module_name = SAM_DEFAULT_BACKEND; - entry.module_params = NULL; - entry.domain_name = "BUILTIN"; - entry.domain_sid = (DOM_SID *)malloc(sizeof(DOM_SID)); - sid_copy(entry.domain_sid, &global_sid_Builtin); - - if (!NT_STATUS_IS_OK(ntstatus = make_sam_methods_backend_entry(context, &methods, &entry))) { - DEBUG(4,("make_sam_methods_backend_entry failed\n")); - return ntstatus; - } - - DLIST_ADD_END(context->methods, methods, tmpmethods); - } else if (!NT_STATUS_IS_OK(ntstatus)) { - DEBUG(2, ("sam_get_methods_by_sid failed for BUILTIN\n")); - return ntstatus; - } - - return NT_STATUS_OK; -} - -static NTSTATUS check_duplicate_backend_entries(SAM_BACKEND_ENTRY **backend_entries, int *nBackends) -{ - int i, j; - - DEBUG(5,("check_duplicate_backend_entries: %d\n", __LINE__)); - - for (i = 0; i < *nBackends; i++) { - for (j = i + 1; j < *nBackends; j++) { - if (sid_equal((*backend_entries)[i].domain_sid, (*backend_entries)[j].domain_sid)) { - DEBUG(0,("two backend modules claim the same domain %s\n", - sid_string_static((*backend_entries)[j].domain_sid))); - return NT_STATUS_INVALID_PARAMETER; - } - } - } - - return NT_STATUS_OK; -} - -NTSTATUS make_sam_context_list(SAM_CONTEXT **context, char **sam_backends_param) -{ - int i = 0, j = 0; - SAM_METHODS *curmethods, *tmpmethods; - int nBackends = 0; - SAM_BACKEND_ENTRY *backends = NULL; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - DEBUG(5,("make_sam_context_from_conf: %d\n", __LINE__)); - - if (!sam_backends_param) { - DEBUG(1, ("no SAM backeds specified!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - if (!NT_STATUS_IS_OK(nt_status = make_sam_context(context))) { - DEBUG(4,("make_sam_context failed\n")); - return nt_status; - } - - while (sam_backends_param[nBackends]) - nBackends++; - - DEBUG(6,("There are %d domains listed with their backends\n", nBackends)); - - if ((backends = (SAM_BACKEND_ENTRY *)malloc(sizeof(*backends)*nBackends)) == NULL) { - DEBUG(0,("make_sam_context_list: failed to allocate backends\n")); - return NT_STATUS_NO_MEMORY; - } - - memset(backends, '\0', sizeof(*backends)*nBackends); - - for (i = 0; i < nBackends; i++) { - DEBUG(8,("processing %s\n",sam_backends_param[i])); - if (!NT_STATUS_IS_OK(nt_status = make_backend_entry(&backends[i], sam_backends_param[i]))) { - DEBUG(4,("make_backend_entry failed\n")); - for (j = 0; j < nBackends; j++) SAFE_FREE(backends[j].domain_sid); - SAFE_FREE(backends); - free_sam_context(context); - return nt_status; - } - } - - if (!NT_STATUS_IS_OK(nt_status = check_duplicate_backend_entries(&backends, &nBackends))) { - DEBUG(4,("check_duplicate_backend_entries failed\n")); - for (j = 0; j < nBackends; j++) SAFE_FREE(backends[j].domain_sid); - SAFE_FREE(backends); - free_sam_context(context); - return nt_status; - } - - for (i = 0; i < nBackends; i++) { - if (!NT_STATUS_IS_OK(nt_status = make_sam_methods_backend_entry(*context, &curmethods, &backends[i]))) { - DEBUG(4,("make_sam_methods_backend_entry failed\n")); - for (j = 0; j < nBackends; j++) SAFE_FREE(backends[j].domain_sid); - SAFE_FREE(backends); - free_sam_context(context); - return nt_status; - } - DLIST_ADD_END((*context)->methods, curmethods, tmpmethods); - } - - for (i = 0; i < nBackends; i++) SAFE_FREE(backends[i].domain_sid); - - SAFE_FREE(backends); - return NT_STATUS_OK; -} - -/****************************************************************** - Make a sam_context from scratch. - *******************************************************************/ - -NTSTATUS make_sam_context(SAM_CONTEXT **context) -{ - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("sam_context internal allocation context"); - - if (!mem_ctx) { - DEBUG(0, ("make_sam_context: talloc init failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - *context = talloc(mem_ctx, sizeof(**context)); - if (!*context) { - DEBUG(0, ("make_sam_context: talloc failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(*context); - - (*context)->mem_ctx = mem_ctx; - - (*context)->free_fn = free_sam_context; - - return NT_STATUS_OK; -} - -/****************************************************************** - Return an already initialised sam_context, to facilitate backward - compatibility (see functions below). - *******************************************************************/ - -static struct sam_context *sam_get_static_context(BOOL reload) -{ - static SAM_CONTEXT *sam_context = NULL; - - if ((sam_context) && (reload)) { - sam_context->free_fn(&sam_context); - sam_context = NULL; - } - - if (!sam_context) { - if (!NT_STATUS_IS_OK(make_sam_context_list(&sam_context, lp_sam_backend()))) { - DEBUG(4,("make_sam_context_list failed\n")); - return NULL; - } - - /* Make sure the required domains (default domain, builtin) are available */ - if (!NT_STATUS_IS_OK(sam_context_check_default_backends(sam_context))) { - DEBUG(4,("sam_context_check_default_backends failed\n")); - return NULL; - } - } - - return sam_context; -} - -/*************************************************************** - Initialize the static context (at smbd startup etc). - - If uninitialised, context will auto-init on first use. - ***************************************************************/ - -BOOL initialize_sam(BOOL reload) -{ - return (sam_get_static_context(reload) != NULL); -} - - -/************************************************************** - External API. This is what the rest of the world calls... -***************************************************************/ - -/****************************************************************** - sam_* functions are used to link the external SAM interface - with the internal backends. These functions lookup the appropriate - backends for the domain and pass on to the function in sam_methods - in the selected backend - - When the context parmater is NULL, the default is used. - *******************************************************************/ - -#define SAM_SETUP_CONTEXT if (!context) \ - context = sam_get_static_context(False);\ - if (!context) {\ - return NT_STATUS_UNSUCCESSFUL; \ - }\ - - - -NTSTATUS sam_get_sec_desc(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *sid, SEC_DESC **sd) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_get_sec_desc: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, sid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_get_sec_desc) { - DEBUG(3, ("sam_get_sec_desc: sam_methods of the domain did not specify sam_get_sec_desc\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_sec_desc(tmp_methods, access_token, sid, sd))) { - DEBUG(4,("sam_get_sec_desc for %s in backend %s failed\n", sid_string_static(sid), tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_set_sec_desc(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *sid, const SEC_DESC *sd) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_set_sec_desc: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, sid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_set_sec_desc) { - DEBUG(3, ("sam_set_sec_desc: sam_methods of the domain did not specify sam_set_sec_desc\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_set_sec_desc(tmp_methods, access_token, sid, sd))) { - DEBUG(4,("sam_set_sec_desc for %s in backend %s failed\n", sid_string_static(sid), tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - - -NTSTATUS sam_lookup_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID *sid, uint32 *type) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_lookup_name: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_name(context, &tmp_methods, domain))) { - DEBUG(4,("sam_get_methods_by_name failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_lookup_name) { - DEBUG(3, ("sam_lookup_name: sam_methods of the domain did not specify sam_lookup_name\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_lookup_name(tmp_methods, access_token, name, sid, type))) { - DEBUG(4,("sam_lookup_name for %s\\%s in backend %s failed\n", - tmp_methods->domain_name, name, tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name, uint32 *type) -{ - SAM_METHODS *tmp_methods; - uint32 rid; - NTSTATUS nt_status; - DOM_SID domainsid; - - DEBUG(5,("sam_lookup_sid: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - sid_copy(&domainsid, sid); - if (!sid_split_rid(&domainsid, &rid)) { - DEBUG(3,("sam_lookup_sid: failed to split the sid\n")); - return NT_STATUS_INVALID_SID; - } - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_lookup_sid) { - DEBUG(3, ("sam_lookup_sid: sam_methods of the domain did not specify sam_lookup_sid\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_lookup_sid(tmp_methods, access_token, mem_ctx, sid, name, type))) { - DEBUG(4,("sam_lookup_name for %s in backend %s failed\n", - sid_string_static(sid), tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - - -NTSTATUS sam_update_domain(const SAM_CONTEXT *context, const SAM_DOMAIN_HANDLE *domain) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_update_domain: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid domain specified */ - SAM_ASSERT(domain && domain->current_sam_methods); - - tmp_methods = domain->current_sam_methods; - - if (!tmp_methods->sam_update_domain) { - DEBUG(3, ("sam_update_domain: sam_methods of the domain did not specify sam_update_domain\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_update_domain(tmp_methods, domain))){ - DEBUG(4,("sam_update_domain in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_enum_domains(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, int32 *domain_count, DOM_SID **domains, char ***domain_names) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - SEC_DESC *sd; - size_t sd_size; - uint32 acc_granted; - int i = 0; - - DEBUG(5,("sam_enum_domains: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid parmaters specified */ - SAM_ASSERT(domain_count && domains && domain_names); - - if (!NT_STATUS_IS_OK(nt_status = samr_make_sam_obj_sd(context->mem_ctx, &sd, &sd_size))) { - DEBUG(4,("samr_make_sam_obj_sd failed\n")); - return nt_status; - } - - if (!se_access_check(sd, access_token, SA_RIGHT_SAM_ENUM_DOMAINS, &acc_granted, &nt_status)) { - DEBUG(3,("sam_enum_domains: ACCESS DENIED\n")); - return nt_status; - } - - tmp_methods= context->methods; - *domain_count = 0; - - while (tmp_methods) { - (*domain_count)++; - tmp_methods= tmp_methods->next; - } - - DEBUG(6,("sam_enum_domains: enumerating %d domains\n", (*domain_count))); - - tmp_methods = context->methods; - - if (((*domains) = malloc( sizeof(DOM_SID) * (*domain_count))) == NULL) { - DEBUG(0,("sam_enum_domains: Out of memory allocating domain SID list\n")); - return NT_STATUS_NO_MEMORY; - } - - if (((*domain_names) = malloc( sizeof(char*) * (*domain_count))) == NULL) { - DEBUG(0,("sam_enum_domains: Out of memory allocating domain name list\n")); - SAFE_FREE((*domains)); - return NT_STATUS_NO_MEMORY; - } - - while (tmp_methods) { - DEBUGADD(7,(" [%d] %s: %s\n", i, tmp_methods->domain_name, sid_string_static(&tmp_methods->domain_sid))); - sid_copy(domains[i],&tmp_methods->domain_sid); - *domain_names[i] = smb_xstrdup(tmp_methods->domain_name); - i++; - tmp_methods= tmp_methods->next; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_lookup_domain(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const char *domain, DOM_SID **domainsid) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - SEC_DESC *sd; - size_t sd_size; - uint32 acc_granted; - - DEBUG(5,("sam_lookup_domain: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid paramters */ - SAM_ASSERT(access_token && domain && domainsid); - - if (!NT_STATUS_IS_OK(nt_status = samr_make_sam_obj_sd(context->mem_ctx, &sd, &sd_size))) { - DEBUG(4,("samr_make_sam_obj_sd failed\n")); - return nt_status; - } - - if (!se_access_check(sd, access_token, SA_RIGHT_SAM_OPEN_DOMAIN, &acc_granted, &nt_status)) { - DEBUG(3,("sam_lookup_domain: ACCESS DENIED\n")); - return nt_status; - } - - tmp_methods= context->methods; - - while (tmp_methods) { - if (strcmp(domain, tmp_methods->domain_name) == 0) { - (*domainsid) = (DOM_SID *)malloc(sizeof(DOM_SID)); - sid_copy((*domainsid), &tmp_methods->domain_sid); - return NT_STATUS_OK; - } - tmp_methods= tmp_methods->next; - } - - return NT_STATUS_NO_SUCH_DOMAIN; -} - - -NTSTATUS sam_get_domain_by_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, SAM_DOMAIN_HANDLE **domain) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_get_domain_by_sid: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && domainsid && domain); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_get_domain_handle) { - DEBUG(3, ("sam_get_domain_by_sid: sam_methods of the domain did not specify sam_get_domain_handle\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_domain_handle(tmp_methods, access_token, access_desired, domain))) { - DEBUG(4,("sam_get_domain_handle for %s in backend %s failed\n", - sid_string_static(domainsid), tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_create_account(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_create_account: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid parmaters */ - SAM_ASSERT(access_token && domainsid && account_name && account); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_create_account) { - DEBUG(3, ("sam_create_account: sam_methods of the domain did not specify sam_create_account\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_create_account(tmp_methods, access_token, access_desired, account_name, acct_ctrl, account))) { - DEBUG(4,("sam_create_account in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_add_account(const SAM_CONTEXT *context, const SAM_ACCOUNT_HANDLE *account) -{ - DOM_SID domainsid; - const DOM_SID *accountsid; - SAM_METHODS *tmp_methods; - uint32 rid; - NTSTATUS nt_status; - - DEBUG(5,("sam_add_account: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid parmaters */ - SAM_ASSERT(account); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_account_sid(account, &accountsid))) { - DEBUG(0,("Can't get account SID\n")); - return nt_status; - } - - sid_copy(&domainsid, accountsid); - if (!sid_split_rid(&domainsid, &rid)) { - DEBUG(3,("sam_get_account_by_sid: failed to split the sid\n")); - return NT_STATUS_INVALID_SID; - } - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_add_account) { - DEBUG(3, ("sam_add_account: sam_methods of the domain did not specify sam_add_account\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_add_account(tmp_methods, account))){ - DEBUG(4,("sam_add_account in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_update_account(const SAM_CONTEXT *context, const SAM_ACCOUNT_HANDLE *account) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_update_account: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid account specified */ - SAM_ASSERT(account && account->current_sam_methods); - - tmp_methods = account->current_sam_methods; - - if (!tmp_methods->sam_update_account) { - DEBUG(3, ("sam_update_account: sam_methods of the domain did not specify sam_update_account\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_update_account(tmp_methods, account))){ - DEBUG(4,("sam_update_account in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_delete_account(const SAM_CONTEXT *context, const SAM_ACCOUNT_HANDLE *account) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_delete_account: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid account specified */ - SAM_ASSERT(account && account->current_sam_methods); - - tmp_methods = account->current_sam_methods; - - if (!tmp_methods->sam_delete_account) { - DEBUG(3, ("sam_delete_account: sam_methods of the domain did not specify sam_delete_account\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_delete_account(tmp_methods, account))){ - DEBUG(4,("sam_delete_account in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_enum_accounts(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *domainsid, uint16 acct_ctrl, int32 *account_count, SAM_ACCOUNT_ENUM **accounts) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_enum_accounts: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && domainsid && account_count && accounts); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_enum_accounts) { - DEBUG(3, ("sam_enum_accounts: sam_methods of the domain did not specify sam_enum_accounts\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_enum_accounts(tmp_methods, access_token, acct_ctrl, account_count, accounts))) { - DEBUG(4,("sam_enum_accounts for domain %s in backend %s failed\n", - tmp_methods->domain_name, tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - - -NTSTATUS sam_get_account_by_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *accountsid, SAM_ACCOUNT_HANDLE **account) -{ - SAM_METHODS *tmp_methods; - uint32 rid; - DOM_SID domainsid; - NTSTATUS nt_status; - - DEBUG(5,("sam_get_account_by_sid: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && accountsid && account); - - sid_copy(&domainsid, accountsid); - if (!sid_split_rid(&domainsid, &rid)) { - DEBUG(3,("sam_get_account_by_sid: failed to split the sid\n")); - return NT_STATUS_INVALID_SID; - } - - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_get_account_by_sid) { - DEBUG(3, ("sam_get_account_by_sid: sam_methods of the domain did not specify sam_get_account_by_sid\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_account_by_sid(tmp_methods, access_token, access_desired, accountsid, account))) { - DEBUG(4,("sam_get_account_by_sid for %s in backend %s failed\n", - sid_string_static(accountsid), tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_get_account_by_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *domain, const char *name, SAM_ACCOUNT_HANDLE **account) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_get_account_by_name: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && domain && name && account); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_name(context, &tmp_methods, domain))) { - DEBUG(4,("sam_get_methods_by_name failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_get_account_by_name) { - DEBUG(3, ("sam_get_account_by_name: sam_methods of the domain did not specify sam_get_account_by_name\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_account_by_name(tmp_methods, access_token, access_desired, name, account))) { - DEBUG(4,("sam_get_account_by_name for %s\\%s in backend %s failed\n", - domain, name, tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_create_group(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, const char *group_name, uint16 group_ctrl, SAM_GROUP_HANDLE **group) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_create_group: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && domainsid && group_name && group); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_create_group) { - DEBUG(3, ("sam_create_group: sam_methods of the domain did not specify sam_create_group\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_create_group(tmp_methods, access_token, access_desired, group_name, group_ctrl, group))) { - DEBUG(4,("sam_create_group in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_add_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group) -{ - DOM_SID domainsid; - const DOM_SID *groupsid; - SAM_METHODS *tmp_methods; - uint32 rid; - NTSTATUS nt_status; - - DEBUG(5,("sam_add_group: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(group); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_group_sid(group, &groupsid))) { - DEBUG(0,("Can't get group SID\n")); - return nt_status; - } - - sid_copy(&domainsid, groupsid); - if (!sid_split_rid(&domainsid, &rid)) { - DEBUG(3,("sam_get_group_by_sid: failed to split the sid\n")); - return NT_STATUS_INVALID_SID; - } - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_add_group) { - DEBUG(3, ("sam_add_group: sam_methods of the domain did not specify sam_add_group\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_add_group(tmp_methods, group))){ - DEBUG(4,("sam_add_group in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_update_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_update_group: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid group specified */ - SAM_ASSERT(group && group->current_sam_methods); - - tmp_methods = group->current_sam_methods; - - if (!tmp_methods->sam_update_group) { - DEBUG(3, ("sam_update_group: sam_methods of the domain did not specify sam_update_group\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_update_group(tmp_methods, group))){ - DEBUG(4,("sam_update_group in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_delete_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_delete_group: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid group specified */ - SAM_ASSERT(group && group->current_sam_methods); - - tmp_methods = group->current_sam_methods; - - if (!tmp_methods->sam_delete_group) { - DEBUG(3, ("sam_delete_group: sam_methods of the domain did not specify sam_delete_group\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_delete_group(tmp_methods, group))){ - DEBUG(4,("sam_delete_group in backend %s failed\n", - tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_enum_groups(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *domainsid, uint16 group_ctrl, uint32 *groups_count, SAM_GROUP_ENUM **groups) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_enum_groups: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && domainsid && groups_count && groups); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_enum_accounts) { - DEBUG(3, ("sam_enum_groups: sam_methods of the domain did not specify sam_enum_groups\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_enum_groups(tmp_methods, access_token, group_ctrl, groups_count, groups))) { - DEBUG(4,("sam_enum_groups for domain %s in backend %s failed\n", - tmp_methods->domain_name, tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_get_group_by_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *groupsid, SAM_GROUP_HANDLE **group) -{ - SAM_METHODS *tmp_methods; - uint32 rid; - NTSTATUS nt_status; - DOM_SID domainsid; - - DEBUG(5,("sam_get_group_by_sid: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && groupsid && group); - - sid_copy(&domainsid, groupsid); - if (!sid_split_rid(&domainsid, &rid)) { - DEBUG(3,("sam_get_group_by_sid: failed to split the sid\n")); - return NT_STATUS_INVALID_SID; - } - - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) { - DEBUG(4,("sam_get_methods_by_sid failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_get_group_by_sid) { - DEBUG(3, ("sam_get_group_by_sid: sam_methods of the domain did not specify sam_get_group_by_sid\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_group_by_sid(tmp_methods, access_token, access_desired, groupsid, group))) { - DEBUG(4,("sam_get_group_by_sid for %s in backend %s failed\n", - sid_string_static(groupsid), tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_get_group_by_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *domain, const char *name, SAM_GROUP_HANDLE **group) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - DEBUG(5,("sam_get_group_by_name: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - SAM_ASSERT(access_token && domain && name && group); - - if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_name(context, &tmp_methods, domain))) { - DEBUG(4,("sam_get_methods_by_name failed\n")); - return nt_status; - } - - if (!tmp_methods->sam_get_group_by_name) { - DEBUG(3, ("sam_get_group_by_name: sam_methods of the domain did not specify sam_get_group_by_name\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_group_by_name(tmp_methods, access_token, access_desired, name, group))) { - DEBUG(4,("sam_get_group_by_name for %s\\%s in backend %s failed\n", - domain, name, tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_add_member_to_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - SAM_SETUP_CONTEXT; - - /* invalid group or member specified */ - SAM_ASSERT(group && group->current_sam_methods && member); - - tmp_methods = group->current_sam_methods; - - if (!tmp_methods->sam_add_member_to_group) { - DEBUG(3, ("sam_add_member_to_group: sam_methods of the domain did not specify sam_add_member_to_group\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_add_member_to_group(tmp_methods, group, member))) { - DEBUG(4,("sam_add_member_to_group in backend %s failed\n", tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; - -} - -NTSTATUS sam_delete_member_from_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - SAM_SETUP_CONTEXT; - - /* invalid group or member specified */ - SAM_ASSERT(group && group->current_sam_methods && member); - - tmp_methods = group->current_sam_methods; - - if (!tmp_methods->sam_delete_member_from_group) { - DEBUG(3, ("sam_delete_member_from_group: sam_methods of the domain did not specify sam_delete_member_from_group\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_delete_member_from_group(tmp_methods, group, member))) { - DEBUG(4,("sam_delete_member_from_group in backend %s failed\n", tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_enum_groupmembers(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group, uint32 *members_count, SAM_GROUP_MEMBER **members) -{ - const SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - SAM_SETUP_CONTEXT; - - /* invalid group specified */ - SAM_ASSERT(group && group->current_sam_methods && members_count && members); - - tmp_methods = group->current_sam_methods; - - if (!tmp_methods->sam_enum_groupmembers) { - DEBUG(3, ("sam_enum_groupmembers: sam_methods of the domain did not specify sam_enum_group_members\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_enum_groupmembers(tmp_methods, group, members_count, members))) { - DEBUG(4,("sam_enum_groupmembers in backend %s failed\n", tmp_methods->backendname)); - return nt_status; - } - - return NT_STATUS_OK; -} - -NTSTATUS sam_get_groups_of_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID **sids, uint16 group_ctrl, uint32 *group_count, SAM_GROUP_ENUM **groups) -{ - SAM_METHODS *tmp_methods; - NTSTATUS nt_status; - - uint32 tmp_group_count; - SAM_GROUP_ENUM *tmp_groups; - - DEBUG(5,("sam_get_groups_of_sid: %d\n", __LINE__)); - - SAM_SETUP_CONTEXT; - - /* invalid sam_context specified */ - SAM_ASSERT(access_token && sids && context && context->methods); - - *group_count = 0; - - *groups = NULL; - - tmp_methods= context->methods; - - while (tmp_methods) { - DEBUG(5,("getting groups from domain \n")); - if (!tmp_methods->sam_get_groups_of_sid) { - DEBUG(3, ("sam_get_groups_of_sid: sam_methods of domain did not specify sam_get_groups_of_sid\n")); - SAFE_FREE(*groups); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_groups_of_sid(tmp_methods, access_token, sids, group_ctrl, &tmp_group_count, &tmp_groups))) { - DEBUG(4,("sam_get_groups_of_sid in backend %s failed\n", tmp_methods->backendname)); - SAFE_FREE(*groups); - return nt_status; - } - - *groups = Realloc(*groups, ((*group_count) + tmp_group_count) * sizeof(SAM_GROUP_ENUM)); - - memcpy(&(*groups)[*group_count], tmp_groups, tmp_group_count); - - SAFE_FREE(tmp_groups); - - *group_count += tmp_group_count; - - tmp_methods = tmp_methods->next; - } - - return NT_STATUS_OK; -} - - |