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.c651
1 files changed, 285 insertions, 366 deletions
diff --git a/source3/sam/gums_tdbsam2.c b/source3/sam/gums_tdbsam2.c
index 217cf6f34e..7fb9a1a997 100644
--- a/source3/sam/gums_tdbsam2.c
+++ b/source3/sam/gums_tdbsam2.c
@@ -19,7 +19,6 @@
*/
#include "includes.h"
-#include "tdbsam2.h"
#include "tdbsam2_parse_info.h"
#if 0
@@ -36,7 +35,9 @@ static int gums_tdbsam2_debug_class = DBGC_ALL;
#define SIDPREFIX "SID_"
#define PRIVILEGEPREFIX "PRIV_"
-#define TDB_FORMAT_STRING "ddB"
+#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)
@@ -51,19 +52,6 @@ struct tdbsam2_enum_objs {
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;
@@ -72,7 +60,6 @@ struct tdbsam2_private_data {
static struct tdbsam2_private_data *ts2_privs;
-
static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size)
{
@@ -81,7 +68,7 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size
int iret;
char *obj_data = NULL;
int data_size = 0;
- int version, type;
+ int version, type, seqnum;
int len;
mem_ctx = talloc_init("init_object_from_buffer");
@@ -93,16 +80,17 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size
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 */
+ /* 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"));
+ DEBUG(3,("init_object_from_buffer: Error, db object has wrong tdbsam version!\n"));
goto done;
}
@@ -116,20 +104,16 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size
switch (type) {
case GUMS_OBJ_DOMAIN:
- iret = gen_parse(mem_ctx, pinfo_tdbsam2_domain_data, (char *)(*go), obj_data);
+ 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_tdbsam2_group_data, (char *)(*go), obj_data);
+ iret = gen_parse(mem_ctx, pinfo_gums_group, (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);
+ iret = gen_parse(mem_ctx, pinfo_gums_user, (char *)(*go), obj_data);
break;
default:
@@ -151,6 +135,62 @@ done:
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)
{
@@ -164,20 +204,16 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *
switch (gums_get_object_type(object)) {
case GUMS_OBJ_DOMAIN:
- genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_domain_data, (char *)object, 0);
+ 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_tdbsam2_group_data, (char *)object, 0);
+ genbuf = gen_dump(mem_ctx, pinfo_gums_group, (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);
+ genbuf = gen_dump(mem_ctx, pinfo_gums_user, (char *)object, 0);
break;
default:
@@ -193,6 +229,7 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *
buflen = tdb_pack(NULL, 0, TDB_FORMAT_STRING,
TDBSAM_VERSION,
object->type,
+ object->seq_num,
strlen(genbuf) + 1, genbuf);
*buffer = talloc(mem_ctx, buflen);
@@ -201,6 +238,7 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *
*len = tdb_pack(*buffer, buflen, TDB_FORMAT_STRING,
TDBSAM_VERSION,
object->type,
+ object->seq_num,
strlen(genbuf) + 1, genbuf);
if (*len != buflen) {
@@ -216,6 +254,49 @@ 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)
@@ -266,7 +347,46 @@ done:
return ret;
}
-static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char* name)
+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;
@@ -277,14 +397,15 @@ static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const ch
fstring sidstr;
int sidstr_len;
- if (!obj || !name)
+ if (!obj || !fullname)
return NT_STATUS_INVALID_PARAMETER;
/* Data is stored in all lower-case */
- fstrcpy(objname, name);
+ fstrcpy(objname, fullname);
strlower_m(objname);
slprintf(keystr, sizeof(keystr)-1, "%s%s", NAMEPREFIX, objname);
+
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
@@ -320,13 +441,52 @@ done:
return ret;
}
-/* store a tdbsam2_object
+/* 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, const GUMS_OBJECT *object, int flag)
+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;
@@ -346,308 +506,65 @@ static NTSTATUS store_object(TDB_CONTEXT *tdb, const GUMS_OBJECT *object, int fl
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;
- }
+ make_full_object_name(tdb, objname, object);
/* 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;
+ if (flag == TDB_MODIFY) {
+ if (!NT_STATUS_IS_OK(ret = get_object_seq_num(tdb, object, &(object->seq_num))))
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;
+ object->seq_num += 1;
}
- /* 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;
-}
+ if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object)))
+ goto done;
-static NTSTATUS data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_object *data)
-{
+ 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);
- NTSTATUS ret;
+ key.dptr = keystr;
+ key.dsize = strlen(keystr) + 1;
- if (!object || !data) {
- DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL structure pointers are accepted here!\n"));
- ret = NT_STATUS_INVALID_PARAMETER;
+ 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;
}
- 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"));
+ 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;
}
- 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;
- }
+/* TODO: update the general database counter */
+/* TODO: update this entry counter too */
done:
+ talloc_destroy(mem_ctx);
return ret;
}
-#endif
/* GUMM object functions */
@@ -788,26 +705,18 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj
goto done;
}
- if (obj_type != GUMS_OBJ_PRIVILEGE) {
- if (!sid) {
- ret = NT_STATUS_INVALID_PARAMETER;
+ 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;
- }
-
- 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_sid(go, sid);
gums_set_object_name(go, name);
gums_set_object_seq_num(go, 1);
- /*obj.data.domain->sec_desc*/
+ /*obj.domain->sec_desc*/
switch (obj_type) {
case GUMS_OBJ_NORMAL_USER:
@@ -829,7 +738,6 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj
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);
@@ -846,10 +754,6 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj
break;
- case GUMS_OBJ_PRIVILEGE:
-
- break;
-
default:
ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
goto done;
@@ -864,6 +768,8 @@ done:
return ret;
}
+/* TODO: handle privileges objects */
+
static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
{
/* TODO: need to address privilege deletion */
@@ -882,7 +788,7 @@ static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
return ret;
}
- slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid));
+ slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(sid));
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
@@ -909,18 +815,7 @@ static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
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;
- }
+ slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go));
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
@@ -956,10 +851,14 @@ static NTSTATUS tdbsam2_get_object_from_sid(GUMS_OBJECT **object, const DOM_SID
}
ret = get_object_by_sid(tdb, object, sid);
- if (!NT_STATUS_IS_OK(ret) || (obj_type && gums_get_object_type(*object) != obj_type)) {
+ 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;
@@ -970,10 +869,11 @@ error:
return ret;
}
-static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *name, const int obj_type)
+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"));
@@ -984,12 +884,27 @@ static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *n
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) || (obj_type && gums_get_object_type(*object) != obj_type)) {
+ 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;
@@ -1072,7 +987,7 @@ static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *h
}
while ((teo->key.dptr != NULL)) {
- int len, version, type, size;
+ int len, version, type, size, seqnum;
char *ptr;
if (strncmp(teo->key.dptr, prefix, preflen)) {
@@ -1099,6 +1014,7 @@ static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *h
len = tdb_unpack (data.dptr, data.dsize, TDB_FORMAT_STRING,
&version,
&type,
+ &seqnum,
&size, &ptr);
if (len == -1) {
@@ -1166,7 +1082,7 @@ static NTSTATUS tdbsam2_enumerate_objects_stop(void *handle)
return NT_STATUS_OK;
}
-static NTSTATUS tdbsam2_set_object(const GUMS_OBJECT *go)
+static NTSTATUS tdbsam2_set_object(GUMS_OBJECT *go)
{
NTSTATUS ret;
TDB_CONTEXT *tdb;
@@ -1200,12 +1116,14 @@ 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);
+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);
+static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
#endif
static void free_tdbsam2_private_data(void **vp)
@@ -1243,6 +1161,7 @@ static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage)
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;
@@ -1280,7 +1199,7 @@ static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage)
gums_init_builtin_domain();
}
- gums_init_domain(get_global_sam_sid(), global_myname());
+ gums_init_domain(get_global_sam_sid(), global_myname(), "The Domain");
}
fns->private_data = &ts2_privs;