summaryrefslogtreecommitdiff
path: root/source3/sam/gums_tdbsam2.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/sam/gums_tdbsam2.c')
-rw-r--r--source3/sam/gums_tdbsam2.c1297
1 files changed, 0 insertions, 1297 deletions
diff --git a/source3/sam/gums_tdbsam2.c b/source3/sam/gums_tdbsam2.c
deleted file mode 100644
index 82e3923f7c..0000000000
--- a/source3/sam/gums_tdbsam2.c
+++ /dev/null
@@ -1,1297 +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.h"
-#include "tdbsam2_parse_info.h"
-
-static int gums_tdbsam2_debug_class = DBGC_ALL;
-/*
-#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_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;
-};
-
-union tdbsam2_data {
- struct tdbsam2_domain_data *domain;
- struct tdbsam2_user_data *user;
- struct tdbsam2_group_data *group;
- struct tdbsam2_priv_data *priv;
-};
-
-struct tdbsam2_object {
- uint32 type;
- uint32 version;
- union tdbsam2_data data;
-};
-
-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;
- 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,
- &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_tdbsam2_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_tdbsam2_domain_data, (char *)(*go), obj_data);
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- iret = gen_parse(mem_ctx, pinfo_tdbsam2_group_data, (char *)(*go), obj_data);
- break;
-
- case GUMS_OBJ_NORMAL_USER:
- iret = gen_parse(mem_ctx, pinfo_tdbsam2_user_data, (char *)(*go), obj_data);
- break;
-
- case GUMS_OBJ_PRIVILEGE:
- iret = gen_parse(mem_ctx, pinfo_tdbsam2_priv_data, (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_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_tdbsam2_domain_data, (char *)object, 0);
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_group_data, (char *)object, 0);
- break;
-
- case GUMS_OBJ_NORMAL_USER:
- genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_user_data, (char *)object, 0);
- break;
-
- case GUMS_OBJ_PRIVILEGE:
- genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_priv_data, (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,
- 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,
- 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 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 get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char* name)
-{
-
- NTSTATUS ret = NT_STATUS_OK;
- TDB_DATA data, key;
- fstring keystr;
- fstring objname;
- DOM_SID sid;
- fstring sidstr;
- int sidstr_len;
-
- if (!obj || !name)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* Data is stored in all lower-case */
- fstrcpy(objname, name);
- 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;
-}
-
-/* store a tdbsam2_object
- * flag: TDB_REPLACE or TDB_MODIFY or TDB_INSERT
- */
-
-static NTSTATUS store_object(TDB_CONTEXT *tdb, const 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;
- }
-
- if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object)))
- goto done;
-
- switch (object->type) {
-
- case GUMS_OBJ_DOMAIN:
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- case GUMS_OBJ_NORMAL_USER:
-
- fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object)));
- slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sidstr);
- break;
-
- default:
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Data is stored in all lower-case */
- fstrcpy(objname, gums_get_object_name(object));
- strlower_m(objname);
-
- slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, objname);
-
- if (object->type != GUMS_OBJ_PRIVILEGE) {
- 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;
- }
- } else {
- key.dptr = namestr;
- 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;
- }
- }
-
-/* TODO: update the general database counter */
-/* TODO: update this entry counter too */
-
-done:
- talloc_destroy(mem_ctx);
- return ret;
-}
-
-#if 0
-static NTSTATUS user_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_user_data *userdata)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- DATA_BLOB pwd;
-
- if (!object || !userdata) {
- DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL pointers are accepted here!\n"));
- return ret;
- }
-
- /* userdata->xcounter */
- /* userdata->sec_desc */
-
- SET_OR_FAIL(gums_set_object_sid(*object, userdata->user_sid), error);
- SET_OR_FAIL(gums_set_object_name(*object, userdata->name), error);
-
- SET_OR_FAIL(gums_set_user_pri_group(*object, userdata->group_sid), error);
-
- if (userdata->description)
- SET_OR_FAIL(gums_set_object_description(*object, userdata->description), error);
-
- if (userdata->full_name)
- SET_OR_FAIL(gums_set_user_fullname(*object, userdata->full_name), error);
-
- if (userdata->home_dir)
- SET_OR_FAIL(gums_set_user_homedir(*object, userdata->home_dir), error);
-
- if (userdata->dir_drive)
- SET_OR_FAIL(gums_set_user_dir_drive(*object, userdata->dir_drive), error);
-
- if (userdata->logon_script)
- SET_OR_FAIL(gums_set_user_logon_script(*object, userdata->logon_script), error);
-
- if (userdata->profile_path)
- SET_OR_FAIL(gums_set_user_profile_path(*object, userdata->profile_path), error);
-
- if (userdata->workstations)
- SET_OR_FAIL(gums_set_user_workstations(*object, userdata->workstations), error);
-
- if (userdata->unknown_str)
- SET_OR_FAIL(gums_set_user_unknown_str(*object, userdata->unknown_str), error);
-
- if (userdata->munged_dial)
- SET_OR_FAIL(gums_set_user_munged_dial(*object, userdata->munged_dial), error);
-
- SET_OR_FAIL(gums_set_user_logon_divs(*object, userdata->logon_divs), error);
-
- if (userdata->hours)
- SET_OR_FAIL(gums_set_user_hours(*object, userdata->hours_len, userdata->hours), error);
-
- SET_OR_FAIL(gums_set_user_unknown_3(*object, userdata->unknown_3), error);
- SET_OR_FAIL(gums_set_user_unknown_5(*object, userdata->unknown_5), error);
- SET_OR_FAIL(gums_set_user_unknown_6(*object, userdata->unknown_6), error);
-
- SET_OR_FAIL(gums_set_user_logon_time(*object, *(userdata->logon_time)), error);
- SET_OR_FAIL(gums_set_user_logoff_time(*object, *(userdata->logoff_time)), error);
- SET_OR_FAIL(gums_set_user_kickoff_time(*object, *(userdata->kickoff_time)), error);
- SET_OR_FAIL(gums_set_user_pass_last_set_time(*object, *(userdata->pass_last_set_time)), error);
- SET_OR_FAIL(gums_set_user_pass_can_change_time(*object, *(userdata->pass_can_change_time)), error);
- SET_OR_FAIL(gums_set_user_pass_must_change_time(*object, *(userdata->pass_must_change_time)), error);
-
- pwd = data_blob(userdata->nt_pw_ptr, NT_HASH_LEN);
- ret = gums_set_user_nt_pwd(*object, pwd);
- data_blob_clear_free(&pwd);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(5, ("user_data_to_gums_object: failed to set nt password!\n"));
- goto error;
- }
- pwd = data_blob(userdata->lm_pw_ptr, LM_HASH_LEN);
- ret = gums_set_user_lm_pwd(*object, pwd);
- data_blob_clear_free(&pwd);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(5, ("user_data_to_gums_object: failed to set lanman password!\n"));
- goto error;
- }
-
- ret = NT_STATUS_OK;
- return ret;
-
-error:
- talloc_destroy((*object)->mem_ctx);
- *object = NULL;
- return ret;
-}
-
-static NTSTATUS group_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_group_data *groupdata)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!object || !groupdata) {
- DEBUG(0, ("tdbsam2_group_data_to_gums_object: no NULL pointers are accepted here!\n"));
- return ret;
- }
-
- /* groupdata->xcounter */
- /* groupdata->sec_desc */
-
- SET_OR_FAIL(gums_set_object_sid(*object, groupdata->group_sid), error);
- SET_OR_FAIL(gums_set_object_name(*object, groupdata->name), error);
-
- if (groupdata->description)
- SET_OR_FAIL(gums_set_object_description(*object, groupdata->description), error);
-
- if (groupdata->count)
- SET_OR_FAIL(gums_set_group_members(*object, groupdata->count, groupdata->members), error);
-
- ret = NT_STATUS_OK;
- return ret;
-
-error:
- talloc_destroy((*object)->mem_ctx);
- *object = NULL;
- return ret;
-}
-
-static NTSTATUS domain_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_domain_data *domdata)
-{
-
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!object || !*object || !domdata) {
- DEBUG(0, ("tdbsam2_domain_data_to_gums_object: no NULL pointers are accepted here!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* domdata->xcounter */
- /* domdata->sec_desc */
-
- SET_OR_FAIL(gums_set_object_sid(*object, domdata->dom_sid), error);
- SET_OR_FAIL(gums_set_object_name(*object, domdata->name), error);
-
- if (domdata->description)
- SET_OR_FAIL(gums_set_object_description(*object, domdata->description), error);
-
- ret = NT_STATUS_OK;
- return ret;
-
-error:
- talloc_destroy((*object)->mem_ctx);
- *object = NULL;
- return ret;
-}
-
-static NTSTATUS priv_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_priv_data *privdata)
-{
-
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!object || !*object || !privdata) {
- DEBUG(0, ("tdbsam2_priv_data_to_gums_object: no NULL pointers are accepted here!\n"));
- return ret;
- }
-
- /* domdata->xcounter */
- /* domdata->sec_desc */
-
- SET_OR_FAIL(gums_set_priv_luid_attr(*object, privdata->privilege), error);
- SET_OR_FAIL(gums_set_object_name(*object, privdata->name), error);
-
- if (privdata->description)
- SET_OR_FAIL(gums_set_object_description(*object, privdata->description), error);
-
- if (privdata->count)
- SET_OR_FAIL(gums_set_priv_members(*object, privdata->count, privdata->members), error);
-
- ret = NT_STATUS_OK;
- return ret;
-
-error:
- talloc_destroy((*object)->mem_ctx);
- *object = NULL;
- return ret;
-}
-
-static NTSTATUS data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_object *data)
-{
-
- NTSTATUS ret;
-
- if (!object || !data) {
- DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL structure pointers are accepted here!\n"));
- ret = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- ret = gums_create_object(object, data->type);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(5, ("tdbsam2_user_data_to_gums_object: error creating gums object!\n"));
- goto done;
- }
-
- switch (data->type) {
-
- case GUMS_OBJ_DOMAIN:
- ret = domain_data_to_gums_object(object, data->data.domain);
- break;
-
- case GUMS_OBJ_NORMAL_USER:
- ret = user_data_to_gums_object(object, data->data.user);
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- ret = group_data_to_gums_object(object, data->data.group);
- break;
-
- case GUMS_OBJ_PRIVILEGE:
- ret = priv_data_to_gums_object(object, data->data.priv);
- break;
-
- default:
- ret = NT_STATUS_UNSUCCESSFUL;
- }
-
-done:
- return ret;
-}
-#endif
-
-/* 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_PRIVILEGE) {
- if (!sid) {
- ret = NT_STATUS_INVALID_PARAMETER;
- 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.data.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_unknown_3(go, 0x00ffffff);
- 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;
-
- case GUMS_OBJ_PRIVILEGE:
-
- 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;
-}
-
-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;
- }
-
- switch (go->type) {
- case GUMS_OBJ_DOMAIN:
- /* FIXME: SHOULD WE ALLOW TO DELETE DOMAINS ? */
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- case GUMS_OBJ_NORMAL_USER:
- slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go));
- break;
- default:
- ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
- goto done;
- }
-
- 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) || (obj_type && gums_get_object_type(*object) != obj_type)) {
- DEBUG(0, ("tdbsam2_get_object_from_sid: %s\n", nt_errstr(ret)));
- 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 *name, const int obj_type)
-{
- NTSTATUS ret;
- TDB_CONTEXT *tdb;
-
- 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;
- }
-
- *object = NULL;
- ret = get_object_by_name(tdb, object, name);
- if (!NT_STATUS_IS_OK(ret) || (obj_type && gums_get_object_type(*object) != obj_type)) {
- DEBUG(0, ("tdbsam2_get_object_from_name: %s\n", nt_errstr(ret)));
- 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;
- 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,
- &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(const 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;
-}
-
- /* 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 (*add_members_to_privilege) (const LUID_ATTR *priv, const DOM_SID **members);
-static NTSTATUS (*delete_members_from_privilege) (const LUID_ATTR *priv, const DOM_SID **members);
-static NTSTATUS (*enumerate_privilege_members) (DOM_SID **members, const LUID_ATTR *priv);
-static NTSTATUS (*get_sid_privileges) (DOM_SID **privs, const DOM_SID *sid);
- /* warning!: set_privilege will overwrite a prior existing privilege if such exist */
-static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
-
-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->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());
- }
-
- 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);
-}