1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

net_vampire: restructure internal code more.

Guenther
(This used to be commit 9557504d70)
This commit is contained in:
Günther Deschner 2008-06-12 12:35:46 +02:00
parent 339d868b17
commit 7a1fa41dca
2 changed files with 468 additions and 324 deletions

View File

@ -158,3 +158,33 @@ typedef struct _accountmap {
uint32_t rid;
const char *cn;
} ACCOUNTMAP;
enum net_samsync_mode {
NET_SAMSYNC_MODE_FETCH_PASSDB = 0,
NET_SAMSYNC_MODE_FETCH_LDIF = 1,
NET_SAMSYNC_MODE_DUMP = 2
};
struct samsync_ldif_context {
GROUPMAP *groupmap;
ACCOUNTMAP *accountmap;
bool initialized;
const char *add_template;
const char *mod_template;
char *add_name;
char *mod_name;
FILE *add_file;
FILE *mod_file;
FILE *ldif_file;
const char *suffix;
int num_alloced;
};
struct samsync_context {
enum net_samsync_mode mode;
const struct dom_sid *domain_sid;
const char *domain_sid_str;
const char *ldif_filename;
struct samsync_ldif_context *ldif;
};

View File

@ -29,13 +29,6 @@
/* uid's and gid's for writing deltas to ldif */
static uint32 ldif_gid = 999;
static uint32 ldif_uid = 999;
/* Keep track of ldap initialization */
static int init_ldap = 1;
enum net_samsync_mode {
NET_SAMSYNC_MODE_FETCH_PASSDB = 0,
NET_SAMSYNC_MODE_DUMP = 1
};
static void display_group_mem_info(uint32_t rid,
struct netr_DELTA_GROUP_MEMBER *r)
@ -177,8 +170,11 @@ static void display_group_info(uint32_t rid, struct netr_DELTA_GROUP *r)
d_printf("desc='%s', rid=%u\n", r->description.string, rid);
}
static NTSTATUS display_sam_entry(struct netr_DELTA_ENUM *r,
const DOM_SID *domain_sid)
static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM *r,
NTSTATUS status,
struct samsync_context *ctx)
{
union netr_DELTA_UNION u = r->delta_union;
union netr_DELTA_ID_UNION id = r->delta_id_union;
@ -332,13 +328,33 @@ static NTSTATUS display_sam_entry(struct netr_DELTA_ENUM *r,
return NT_STATUS_OK;
}
static NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM_ARRAY *r,
NTSTATUS status,
struct samsync_context *ctx)
{
int i;
for (i = 0; i < r->num_deltas; i++) {
display_sam_entry(mem_ctx, database_id, &r->delta_enum[i], status, ctx);
}
return NT_STATUS_OK;
}
typedef NTSTATUS (*samsync_fn_t)(TALLOC_CTX *,
enum netr_SamDatabaseID,
struct netr_DELTA_ENUM_ARRAY *,
NTSTATUS,
struct samsync_context *);
static NTSTATUS process_database(struct rpc_pipe_client *pipe_hnd,
enum netr_SamDatabaseID database_id,
enum net_samsync_mode mode,
NTSTATUS (*callback_fn)(struct netr_DELTA_ENUM *, const DOM_SID *), const DOM_SID *domain_sid)
samsync_fn_t callback_fn,
struct samsync_context *ctx)
{
NTSTATUS result;
int i;
TALLOC_CTX *mem_ctx;
const char *logon_server = pipe_hnd->desthost;
const char *computername = global_myname();
@ -355,12 +371,15 @@ static NTSTATUS process_database(struct rpc_pipe_client *pipe_hnd,
return NT_STATUS_NO_MEMORY;
}
switch (mode) {
switch (ctx->mode) {
case NET_SAMSYNC_MODE_DUMP:
action = "Dumping";
action = "Dumping (to stdout)";
break;
case NET_SAMSYNC_MODE_FETCH_PASSDB:
action = "Fetching";
action = "Fetching (to passdb)";
break;
case NET_SAMSYNC_MODE_FETCH_LDIF:
action = "Fetching (to ldif)";
break;
default:
action = "Unknown";
@ -369,16 +388,16 @@ static NTSTATUS process_database(struct rpc_pipe_client *pipe_hnd,
switch (database_id) {
case SAM_DATABASE_DOMAIN:
d_printf("%s DOMAIN database\n", action);
d_fprintf(stderr, "%s DOMAIN database\n", action);
break;
case SAM_DATABASE_BUILTIN:
d_printf("%s BUILTIN database\n", action);
d_fprintf(stderr, "%s BUILTIN database\n", action);
break;
case SAM_DATABASE_PRIVS:
d_printf("%s PRIVS databases\n", action);
d_fprintf(stderr, "%s PRIVS databases\n", action);
break;
default:
d_printf("%s unknown database type %u\n",
d_fprintf(stderr, "%s unknown database type %u\n",
action, database_id);
break;
}
@ -398,6 +417,9 @@ static NTSTATUS process_database(struct rpc_pipe_client *pipe_hnd,
&sync_context,
&delta_enum_array,
0xffff);
if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
return result;
}
/* Check returned credentials. */
if (!netlogon_creds_client_check(pipe_hnd->dc,
@ -418,14 +440,14 @@ static NTSTATUS process_database(struct rpc_pipe_client *pipe_hnd,
database_id,
delta_enum_array);
/* Display results */
for (i = 0; i < delta_enum_array->num_deltas; i++) {
callback_fn(&delta_enum_array->delta_enum[i],
domain_sid);
}
/* Process results */
callback_fn(mem_ctx, database_id, delta_enum_array, result, ctx);
TALLOC_FREE(delta_enum_array);
/* Increment sync_context */
sync_context += 1;
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
talloc_destroy(mem_ctx);
@ -443,17 +465,22 @@ NTSTATUS rpc_samdump_internals(struct net_context *c,
int argc,
const char **argv)
{
struct samsync_context *ctx;
ctx = TALLOC_ZERO_P(mem_ctx, struct samsync_context);
NT_STATUS_HAVE_NO_MEMORY(ctx);
ctx->mode = NET_SAMSYNC_MODE_DUMP;
ctx->domain_sid = domain_sid;
process_database(pipe_hnd, SAM_DATABASE_DOMAIN,
NET_SAMSYNC_MODE_DUMP,
display_sam_entry, domain_sid);
display_sam_entries, ctx);
process_database(pipe_hnd, SAM_DATABASE_BUILTIN,
NET_SAMSYNC_MODE_DUMP,
display_sam_entry, domain_sid);
display_sam_entries, ctx);
process_database(pipe_hnd, SAM_DATABASE_PRIVS,
NET_SAMSYNC_MODE_DUMP,
display_sam_entry, domain_sid);
display_sam_entries, ctx);
return NT_STATUS_OK;
}
@ -1116,7 +1143,10 @@ static NTSTATUS fetch_domain_info(uint32_t rid,
return NT_STATUS_OK;
}
static NTSTATUS fetch_sam_entry(struct netr_DELTA_ENUM *r, const DOM_SID *dom_sid)
static NTSTATUS fetch_sam_entry(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM *r,
struct samsync_context *ctx)
{
switch(r->delta_type) {
case NETR_DELTA_USER:
@ -1134,12 +1164,12 @@ static NTSTATUS fetch_sam_entry(struct netr_DELTA_ENUM *r, const DOM_SID *dom_si
case NETR_DELTA_ALIAS:
fetch_alias_info(r->delta_id_union.rid,
r->delta_union.alias,
dom_sid);
ctx->domain_sid);
break;
case NETR_DELTA_ALIAS_MEMBER:
fetch_alias_mem(r->delta_id_union.rid,
r->delta_union.alias_member,
dom_sid);
ctx->domain_sid);
break;
case NETR_DELTA_DOMAIN:
fetch_domain_info(r->delta_id_union.rid,
@ -1202,8 +1232,28 @@ static NTSTATUS fetch_sam_entry(struct netr_DELTA_ENUM *r, const DOM_SID *dom_si
return NT_STATUS_OK;
}
static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char
*builtin_sid, FILE *add_fd)
static NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM_ARRAY *r,
NTSTATUS status,
struct samsync_context *ctx)
{
int i;
for (i = 0; i < r->num_deltas; i++) {
fetch_sam_entry(mem_ctx, database_id, &r->delta_enum[i], ctx);
}
return NT_STATUS_OK;
}
/****************************************************************
****************************************************************/
static NTSTATUS populate_ldap_for_ldif(const char *sid,
const char *suffix,
const char *builtin_sid,
FILE *add_fd)
{
const char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix;
char *user_attr=NULL, *group_attr=NULL;
@ -1459,10 +1509,13 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch
return NT_STATUS_OK;
}
/****************************************************************
****************************************************************/
static NTSTATUS map_populate_groups(TALLOC_CTX *mem_ctx,
GROUPMAP *groupmap,
ACCOUNTMAP *accountmap,
fstring sid,
const char *sid,
const char *suffix,
const char *builtin_sid)
{
@ -1631,20 +1684,20 @@ static int fprintf_attr(FILE *add_fd, const char *attr_name,
return res;
}
/****************************************************************
****************************************************************/
static NTSTATUS fetch_group_info_to_ldif(TALLOC_CTX *mem_ctx,
struct netr_DELTA_GROUP *r,
GROUPMAP *groupmap,
FILE *add_fd,
fstring sid,
char *suffix)
const char *sid,
const char *suffix)
{
fstring groupname;
const char *groupname = r->group_name.string;
uint32 grouptype = 0, g_rid = 0;
char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
/* Get the group name */
fstrcpy(groupname, r->group_name.string);
/* Set up the group type (always 2 for group info) */
grouptype = 2;
@ -1694,12 +1747,16 @@ static NTSTATUS fetch_group_info_to_ldif(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
/****************************************************************
****************************************************************/
static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
struct netr_DELTA_USER *r,
GROUPMAP *groupmap,
ACCOUNTMAP *accountmap,
FILE *add_fd,
fstring sid, char *suffix,
const char *sid,
const char *suffix,
int alloced)
{
fstring username, logonscript, homedrive, homepath = "", homedir = "";
@ -1841,12 +1898,16 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
/****************************************************************
****************************************************************/
static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
struct netr_DELTA_ALIAS *r,
GROUPMAP *groupmap,
FILE *add_fd, fstring sid,
char *suffix,
unsigned db_type)
FILE *add_fd,
const char *sid,
const char *suffix,
enum netr_SamDatabaseID database_id)
{
fstring aliasname, description;
uint32 grouptype = 0, g_rid = 0;
@ -1859,7 +1920,7 @@ static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
fstrcpy(description, r->description.string);
/* Set up the group type */
switch (db_type) {
switch (database_id) {
case SAM_DATABASE_DOMAIN:
grouptype = 4;
break;
@ -1919,6 +1980,9 @@ static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
/****************************************************************
****************************************************************/
static NTSTATUS fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER *r,
uint32_t id_rid,
GROUPMAP *groupmap,
@ -1964,85 +2028,25 @@ static NTSTATUS fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER *r,
return NT_STATUS_OK;
}
static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
uint32 db_type,
const DOM_SID *dom_sid,
const char *user_file)
/****************************************************************
****************************************************************/
static NTSTATUS ldif_init_context(TALLOC_CTX *mem_ctx,
struct samsync_context *ctx,
enum netr_SamDatabaseID database_id)
{
char *suffix;
const char *builtin_sid = "S-1-5-32";
char *add_name = NULL, *mod_name = NULL;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
struct samsync_ldif_context *r;
const char *add_template = "/tmp/add.ldif.XXXXXX";
const char *mod_template = "/tmp/mod.ldif.XXXXXX";
fstring sid, domainname;
NTSTATUS ret = NT_STATUS_OK, result;
int k;
TALLOC_CTX *mem_ctx;
uint32 num_deltas;
FILE *add_file = NULL, *mod_file = NULL, *ldif_file = NULL;
int num_alloced = 0, g_index = 0, a_index = 0;
const char *logon_server = pipe_hnd->desthost;
const char *computername = global_myname();
struct netr_Authenticator credential;
struct netr_Authenticator return_authenticator;
enum netr_SamDatabaseID database_id = db_type;
uint16_t restart_state = 0;
uint32_t sync_context = 0;
DATA_BLOB session_key;
const char *builtin_sid = "S-1-5-32";
/* Set up array for mapping accounts to groups */
/* Array element is the group rid */
GROUPMAP *groupmap = NULL;
/* Set up array for mapping account rid's to cn's */
/* Array element is the account rid */
ACCOUNTMAP *accountmap = NULL;
if (!(mem_ctx = talloc_init("fetch_database"))) {
return NT_STATUS_NO_MEMORY;
if (ctx->ldif && ctx->ldif->initialized) {
return NT_STATUS_OK;
}
/* Ensure we have an output file */
if (user_file)
ldif_file = fopen(user_file, "a");
else
ldif_file = stdout;
if (!ldif_file) {
fprintf(stderr, "Could not open %s\n", user_file);
DEBUG(1, ("Could not open %s\n", user_file));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
add_name = talloc_strdup(mem_ctx, add_template);
mod_name = talloc_strdup(mem_ctx, mod_template);
if (!add_name || !mod_name) {
ret = NT_STATUS_NO_MEMORY;
goto done;
}
/* Open the add and mod ldif files */
if (!(add_file = fdopen(smb_mkstemp(add_name),"w"))) {
DEBUG(1, ("Could not open %s\n", add_name));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!(mod_file = fdopen(smb_mkstemp(mod_name),"w"))) {
DEBUG(1, ("Could not open %s\n", mod_name));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Get the sid */
sid_to_fstring(sid, dom_sid);
/* Get the ldap suffix */
suffix = lp_ldap_suffix();
if (suffix == NULL || strcmp(suffix, "") == 0) {
DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
exit(1);
}
r = TALLOC_ZERO_P(mem_ctx, struct samsync_ldif_context);
NT_STATUS_HAVE_NO_MEMORY(r);
/* Get other smb.conf data */
if (!(lp_workgroup()) || !*(lp_workgroup())) {
@ -2050,238 +2054,344 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
exit(1);
}
/* Get the ldap suffix */
r->suffix = lp_ldap_suffix();
if (r->suffix == NULL || strcmp(r->suffix, "") == 0) {
DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
exit(1);
}
/* Get the sid */
ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
NT_STATUS_HAVE_NO_MEMORY(ctx->domain_sid_str);
/* Ensure we have an output file */
if (ctx->ldif_filename) {
r->ldif_file = fopen(ctx->ldif_filename, "a");
} else {
r->ldif_file = stdout;
}
if (!r->ldif_file) {
fprintf(stderr, "Could not open %s\n", ctx->ldif_filename);
DEBUG(1, ("Could not open %s\n", ctx->ldif_filename));
status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
r->add_template = talloc_strdup(mem_ctx, add_template);
r->mod_template = talloc_strdup(mem_ctx, mod_template);
if (!r->add_template || !r->mod_template) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
r->add_name = talloc_strdup(mem_ctx, add_template);
r->mod_name = talloc_strdup(mem_ctx, mod_template);
if (!r->add_name || !r->mod_name) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
/* Open the add and mod ldif files */
if (!(r->add_file = fdopen(smb_mkstemp(r->add_name),"w"))) {
DEBUG(1, ("Could not open %s\n", r->add_name));
status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!(r->mod_file = fdopen(smb_mkstemp(r->mod_name),"w"))) {
DEBUG(1, ("Could not open %s\n", r->mod_name));
status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Allocate initial memory for groupmap and accountmap arrays */
if (init_ldap == 1) {
groupmap = TALLOC_ZERO_ARRAY(mem_ctx, GROUPMAP, 8);
accountmap = TALLOC_ZERO_ARRAY(mem_ctx, ACCOUNTMAP, 8);
if (groupmap == NULL || accountmap == NULL) {
DEBUG(1,("GROUPMAP malloc failed\n"));
ret = NT_STATUS_NO_MEMORY;
goto done;
}
/* Remember how many we malloced */
num_alloced = 8;
/* Initial database population */
ret = populate_ldap_for_ldif(sid, suffix, builtin_sid, add_file);
if (!NT_STATUS_IS_OK(ret)) {
goto done;
}
ret = map_populate_groups(mem_ctx, groupmap, accountmap, sid, suffix,
builtin_sid);
if (!NT_STATUS_IS_OK(ret)) {
goto done;
}
/* Don't do this again */
init_ldap = 0;
r->groupmap = TALLOC_ZERO_ARRAY(mem_ctx, GROUPMAP, 8);
r->accountmap = TALLOC_ZERO_ARRAY(mem_ctx, ACCOUNTMAP, 8);
if (r->groupmap == NULL || r->accountmap == NULL) {
DEBUG(1,("GROUPMAP talloc failed\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
/* Announce what we are doing */
switch( db_type ) {
case SAM_DATABASE_DOMAIN:
d_fprintf(stderr, "Fetching DOMAIN database\n");
break;
case SAM_DATABASE_BUILTIN:
d_fprintf(stderr, "Fetching BUILTIN database\n");
break;
case SAM_DATABASE_PRIVS:
d_fprintf(stderr, "Fetching PRIVS databases\n");
break;
default:
d_fprintf(stderr,
"Fetching unknown database type %u\n",
db_type );
break;
}
/* Remember how many we malloced */
r->num_alloced = 8;
do {
struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
/* Initial database population */
if (database_id == SAM_DATABASE_DOMAIN) {
netlogon_creds_client_step(pipe_hnd->dc, &credential);
result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx,
logon_server,
computername,
&credential,
&return_authenticator,
database_id,
restart_state,
&sync_context,
&delta_enum_array,
0xffff);
/* Check returned credentials. */
if (!netlogon_creds_client_check(pipe_hnd->dc,
&return_authenticator.cred)) {
DEBUG(0,("credentials chain check failed\n"));
return NT_STATUS_ACCESS_DENIED;
}
if (NT_STATUS_IS_ERR(result)) {
break;
}
session_key = data_blob_const(pipe_hnd->dc->sess_key, 16);
samsync_fix_delta_array(mem_ctx,
&session_key,
true,
database_id,
delta_enum_array);
num_deltas = delta_enum_array->num_deltas;
/* Re-allocate memory for groupmap and accountmap arrays */
groupmap = TALLOC_REALLOC_ARRAY(mem_ctx, groupmap, GROUPMAP,
num_deltas+num_alloced);
accountmap = TALLOC_REALLOC_ARRAY(mem_ctx, accountmap, ACCOUNTMAP,
num_deltas+num_alloced);
if (groupmap == NULL || accountmap == NULL) {
DEBUG(1,("GROUPMAP talloc failed\n"));
ret = NT_STATUS_NO_MEMORY;
status = populate_ldap_for_ldif(ctx->domain_sid_str,
r->suffix,
builtin_sid,
r->add_file);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
/* Initialize the new records */
memset(&groupmap[num_alloced], 0,
sizeof(GROUPMAP)*num_deltas);
memset(&accountmap[num_alloced], 0,
sizeof(ACCOUNTMAP)*num_deltas);
status = map_populate_groups(mem_ctx,
r->groupmap,
r->accountmap,
ctx->domain_sid_str,
r->suffix,
builtin_sid);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
/* Remember how many we alloced this time */
num_alloced += num_deltas;
r->initialized = true;
/* Loop through the deltas */
for (k=0; k<num_deltas; k++) {
ctx->ldif = r;
union netr_DELTA_UNION u =
delta_enum_array->delta_enum[k].delta_union;
union netr_DELTA_ID_UNION id =
delta_enum_array->delta_enum[k].delta_id_union;
return NT_STATUS_OK;
done:
TALLOC_FREE(r);
return status;
}
switch(delta_enum_array->delta_enum[k].delta_type) {
case NETR_DELTA_DOMAIN:
/* Is this case needed? */
fstrcpy(domainname,
u.domain->domain_name.string);
break;
/****************************************************************
****************************************************************/
case NETR_DELTA_GROUP:
fetch_group_info_to_ldif(mem_ctx,
u.group,
&groupmap[g_index],
add_file, sid, suffix);
g_index++;
break;
static void ldif_free_context(struct samsync_ldif_context *r)
{
if (!r) {
return;
}
case NETR_DELTA_USER:
fetch_account_info_to_ldif(mem_ctx,
u.user, groupmap,
&accountmap[a_index], add_file,
sid, suffix, num_alloced);
a_index++;
break;
/* Close and delete the ldif files */
if (r->add_file) {
fclose(r->add_file);
}
case NETR_DELTA_ALIAS:
fetch_alias_info_to_ldif(mem_ctx,
u.alias, &groupmap[g_index],
add_file, sid, suffix, db_type);
g_index++;
break;
if ((r->add_name != NULL) &&
strcmp(r->add_name, r->add_template) && (unlink(r->add_name))) {
DEBUG(1,("unlink(%s) failed, error was (%s)\n",
r->add_name, strerror(errno)));
}
case NETR_DELTA_GROUP_MEMBER:
fetch_groupmem_info_to_ldif(
u.group_member, id.rid,
groupmap, accountmap,
mod_file, num_alloced);
break;
if (r->mod_file) {
fclose(r->mod_file);
}
case NETR_DELTA_ALIAS_MEMBER:
case NETR_DELTA_POLICY:
case NETR_DELTA_ACCOUNT:
case NETR_DELTA_TRUSTED_DOMAIN:
case NETR_DELTA_SECRET:
case NETR_DELTA_RENAME_GROUP:
case NETR_DELTA_RENAME_USER:
case NETR_DELTA_RENAME_ALIAS:
case NETR_DELTA_DELETE_GROUP:
case NETR_DELTA_DELETE_USER:
case NETR_DELTA_MODIFY_COUNT:
default:
break;
} /* end of switch */
} /* end of for loop */
if ((r->mod_name != NULL) &&
strcmp(r->mod_name, r->mod_template) && (unlink(r->mod_name))) {
DEBUG(1,("unlink(%s) failed, error was (%s)\n",
r->mod_name, strerror(errno)));
}
/* Increment sync_context */
sync_context += 1;
if (r->ldif_file && (r->ldif_file != stdout)) {
fclose(r->ldif_file);
}
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
TALLOC_FREE(r);
}
/****************************************************************
****************************************************************/
static void ldif_write_output(enum netr_SamDatabaseID database_id,
struct samsync_context *ctx)
{
struct samsync_ldif_context *l = ctx->ldif;
/* Write ldif data to the user's file */
if (db_type == SAM_DATABASE_DOMAIN) {
fprintf(ldif_file,
if (database_id == SAM_DATABASE_DOMAIN) {
fprintf(l->ldif_file,
"# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
fprintf(ldif_file,
fprintf(l->ldif_file,
"# =================================\n\n");
fflush(ldif_file);
} else if (db_type == SAM_DATABASE_BUILTIN) {
fprintf(ldif_file,
fflush(l->ldif_file);
} else if (database_id == SAM_DATABASE_BUILTIN) {
fprintf(l->ldif_file,
"# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
fprintf(ldif_file,
fprintf(l->ldif_file,
"# ==================================\n\n");
fflush(ldif_file);
fflush(l->ldif_file);
}
fseek(add_file, 0, SEEK_SET);
transfer_file(fileno(add_file), fileno(ldif_file), (size_t) -1);
fseek(l->add_file, 0, SEEK_SET);
transfer_file(fileno(l->add_file), fileno(l->ldif_file), (size_t) -1);
if (db_type == SAM_DATABASE_DOMAIN) {
fprintf(ldif_file,
if (database_id == SAM_DATABASE_DOMAIN) {
fprintf(l->ldif_file,
"# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
fprintf(ldif_file,
fprintf(l->ldif_file,
"# ====================================\n\n");
fflush(ldif_file);
} else if (db_type == SAM_DATABASE_BUILTIN) {
fprintf(ldif_file,
fflush(l->ldif_file);
} else if (database_id == SAM_DATABASE_BUILTIN) {
fprintf(l->ldif_file,
"# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
fprintf(ldif_file,
fprintf(l->ldif_file,
"# =====================================\n\n");
fflush(ldif_file);
fflush(l->ldif_file);
}
fseek(mod_file, 0, SEEK_SET);
transfer_file(fileno(mod_file), fileno(ldif_file), (size_t) -1);
fseek(l->mod_file, 0, SEEK_SET);
transfer_file(fileno(l->mod_file), fileno(l->ldif_file), (size_t) -1);
}
/****************************************************************
****************************************************************/
done:
/* Close and delete the ldif files */
if (add_file) {
fclose(add_file);
static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM *r,
struct samsync_context *ctx,
uint32_t *a_index,
uint32_t *g_index)
{
union netr_DELTA_UNION u = r->delta_union;
union netr_DELTA_ID_UNION id = r->delta_id_union;
struct samsync_ldif_context *l = ctx->ldif;
switch (r->delta_type) {
case NETR_DELTA_DOMAIN:
break;
case NETR_DELTA_GROUP:
fetch_group_info_to_ldif(mem_ctx,
u.group,
&l->groupmap[*g_index],
l->add_file,
ctx->domain_sid_str,
l->suffix);
(*g_index)++;
break;
case NETR_DELTA_USER:
fetch_account_info_to_ldif(mem_ctx,
u.user,
l->groupmap,
&l->accountmap[*a_index],
l->add_file,
ctx->domain_sid_str,
l->suffix,
l->num_alloced);
(*a_index)++;
break;
case NETR_DELTA_ALIAS:
fetch_alias_info_to_ldif(mem_ctx,
u.alias,
&l->groupmap[*g_index],
l->add_file,
ctx->domain_sid_str,
l->suffix,
database_id);
(*g_index)++;
break;
case NETR_DELTA_GROUP_MEMBER:
fetch_groupmem_info_to_ldif(u.group_member,
id.rid,
l->groupmap,
l->accountmap,
l->mod_file,
l->num_alloced);
break;
case NETR_DELTA_ALIAS_MEMBER:
case NETR_DELTA_POLICY:
case NETR_DELTA_ACCOUNT:
case NETR_DELTA_TRUSTED_DOMAIN:
case NETR_DELTA_SECRET:
case NETR_DELTA_RENAME_GROUP:
case NETR_DELTA_RENAME_USER:
case NETR_DELTA_RENAME_ALIAS:
case NETR_DELTA_DELETE_GROUP:
case NETR_DELTA_DELETE_USER:
case NETR_DELTA_MODIFY_COUNT:
default:
break;
} /* end of switch */
return NT_STATUS_OK;
}
/****************************************************************
****************************************************************/
static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
struct samsync_context *ctx,
uint32_t num_entries)
{
struct samsync_ldif_context *l = ctx->ldif;
if (!l) {
return NT_STATUS_INVALID_PARAMETER;
}
if ((add_name != NULL) &&
strcmp(add_name, add_template) && (unlink(add_name))) {
DEBUG(1,("unlink(%s) failed, error was (%s)\n",
add_name, strerror(errno)));
/* Re-allocate memory for groupmap and accountmap arrays */
l->groupmap = TALLOC_REALLOC_ARRAY(mem_ctx,
l->groupmap,
GROUPMAP,
num_entries + l->num_alloced);
l->accountmap = TALLOC_REALLOC_ARRAY(mem_ctx,
l->accountmap,
ACCOUNTMAP,
num_entries + l->num_alloced);
if (l->groupmap == NULL || l->accountmap == NULL) {
DEBUG(1,("GROUPMAP talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
if (mod_file) {
fclose(mod_file);
/* Initialize the new records */
memset(&(l->groupmap[l->num_alloced]), 0,
sizeof(GROUPMAP) * num_entries);
memset(&(l->accountmap[l->num_alloced]), 0,
sizeof(ACCOUNTMAP) * num_entries);
/* Remember how many we alloced this time */
l->num_alloced += num_entries;
return NT_STATUS_OK;
}
/****************************************************************
****************************************************************/
static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM_ARRAY *r,
NTSTATUS result,
struct samsync_context *ctx)
{
NTSTATUS status;
int i;
uint32_t g_index = 0, a_index = 0;
status = ldif_init_context(mem_ctx, ctx, database_id);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
if ((mod_name != NULL) &&
strcmp(mod_name, mod_template) && (unlink(mod_name))) {
DEBUG(1,("unlink(%s) failed, error was (%s)\n",
mod_name, strerror(errno)));
status = ldif_realloc_maps(mem_ctx, ctx, r->num_deltas);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
if (ldif_file && (ldif_file != stdout)) {
fclose(ldif_file);
for (i = 0; i < r->num_deltas; i++) {
status = fetch_sam_entry_ldif(mem_ctx, database_id,
&r->delta_enum[i], ctx,
&g_index, &a_index);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
}
/* Return */
talloc_destroy(mem_ctx);
return ret;
/* This was the last query */
if (NT_STATUS_IS_OK(result)) {
ldif_write_output(database_id, ctx);
ldif_free_context(ctx->ldif);
ctx->ldif = NULL;
}
return NT_STATUS_OK;
failed:
ldif_free_context(ctx->ldif);
return status;
}
/**
@ -2319,6 +2429,11 @@ NTSTATUS rpc_vampire_internals(struct net_context *c,
NTSTATUS result;
fstring my_dom_sid_str;
fstring rem_dom_sid_str;
struct samsync_context *ctx;
samsync_fn_t *fn;
ctx = TALLOC_ZERO_P(mem_ctx, struct samsync_context);
NT_STATUS_HAVE_NO_MEMORY(ctx);
if (!sid_equal(domain_sid, get_global_sam_sid())) {
d_printf("Cannot import users from %s at this time, "
@ -2337,14 +2452,18 @@ NTSTATUS rpc_vampire_internals(struct net_context *c,
}
if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) {
result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_DOMAIN,
domain_sid, argv[1]);
} else {
result = process_database(pipe_hnd, SAM_DATABASE_DOMAIN,
NET_SAMSYNC_MODE_FETCH_PASSDB,
fetch_sam_entry, domain_sid);
}
ctx->mode = NET_SAMSYNC_MODE_FETCH_LDIF;
ctx->ldif_filename = argv[1];
fn = (samsync_fn_t *)fetch_sam_entries_ldif;
} else {
ctx->mode = NET_SAMSYNC_MODE_FETCH_PASSDB;
fn = (samsync_fn_t *)fetch_sam_entries;
}
/* fetch domain */
ctx->domain_sid = domain_sid;
result = process_database(pipe_hnd, SAM_DATABASE_DOMAIN,
(samsync_fn_t)fn, ctx);
if (!NT_STATUS_IS_OK(result)) {
d_fprintf(stderr, "Failed to fetch domain database: %s\n",
nt_errstr(result));
@ -2354,15 +2473,10 @@ NTSTATUS rpc_vampire_internals(struct net_context *c,
goto fail;
}
if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) {
result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_BUILTIN,
&global_sid_Builtin, argv[1]);
} else {
result = process_database(pipe_hnd, SAM_DATABASE_BUILTIN,
NET_SAMSYNC_MODE_FETCH_PASSDB,
fetch_sam_entry, &global_sid_Builtin);
}
/* fetch builtin */
ctx->domain_sid = &global_sid_Builtin;
result = process_database(pipe_hnd, SAM_DATABASE_BUILTIN,
(samsync_fn_t)fn, ctx);
if (!NT_STATUS_IS_OK(result)) {
d_fprintf(stderr, "Failed to fetch builtin database: %s\n",
nt_errstr(result));