NTSTATUS libnet_samsync_init_context(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid, struct samsync_context **ctx_p) { struct samsync_context *ctx; *ctx_p = NULL; ctx = TALLOC_ZERO_P(mem_ctx, struct samsync_context); NT_STATUS_HAVE_NO_MEMORY(ctx); if (domain_sid) { ctx->domain_sid = sid_dup_talloc(mem_ctx, domain_sid); NT_STATUS_HAVE_NO_MEMORY(ctx->domain_sid); ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid); NT_STATUS_HAVE_NO_MEMORY(ctx->domain_sid_str); } *ctx_p = ctx; return NT_STATUS_OK; }
SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, enum security_descriptor_revision revision, uint16 type, const DOM_SID *owner_sid, const DOM_SID *grp_sid, SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size) { SEC_DESC *dst; uint32 offset = 0; *sd_size = 0; if(( dst = TALLOC_ZERO_P(ctx, SEC_DESC)) == NULL) return NULL; dst->revision = revision; dst->type = type; if (sacl) dst->type |= SEC_DESC_SACL_PRESENT; if (dacl) dst->type |= SEC_DESC_DACL_PRESENT; dst->owner_sid = NULL; dst->group_sid = NULL; dst->sacl = NULL; dst->dacl = NULL; if(owner_sid && ((dst->owner_sid = sid_dup_talloc(dst,owner_sid)) == NULL)) goto error_exit; if(grp_sid && ((dst->group_sid = sid_dup_talloc(dst,grp_sid)) == NULL)) goto error_exit; if(sacl && ((dst->sacl = dup_sec_acl(dst, sacl)) == NULL)) goto error_exit; if(dacl && ((dst->dacl = dup_sec_acl(dst, dacl)) == NULL)) goto error_exit; offset = SEC_DESC_HEADER_SIZE; /* * Work out the linearization sizes. */ if (dst->sacl != NULL) { offset += dst->sacl->size; } if (dst->dacl != NULL) { offset += dst->dacl->size; } if (dst->owner_sid != NULL) { offset += ndr_size_dom_sid(dst->owner_sid, 0); } if (dst->group_sid != NULL) { offset += ndr_size_dom_sid(dst->group_sid, 0); } *sd_size = (size_t)offset; return dst; error_exit: *sd_size = 0; return NULL; }
NTSTATUS rpc_vampire_ldif_internals(struct net_context *c, const DOM_SID *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status; struct samsync_context *ctx = NULL; status = libnet_samsync_init_context(mem_ctx, domain_sid, &ctx); if (!NT_STATUS_IS_OK(status)) { return status; } if (argc >= 1) { ctx->output_filename = argv[0]; } if (argc >= 2) { parse_samsync_partial_replication_objects(ctx, argc-1, argv+1, &ctx->single_object_replication, &ctx->objects, &ctx->num_objects); } ctx->mode = NET_SAMSYNC_MODE_FETCH_LDIF; ctx->cli = pipe_hnd; ctx->ops = &libnet_samsync_ldif_ops; ctx->domain_name = domain_name; ctx->force_full_replication = c->opt_force_full_repl ? true : false; ctx->clean_old_entries = c->opt_clean_old_entries ? true : false; /* fetch domain */ status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx); if (!NT_STATUS_IS_OK(status) && ctx->error_message) { d_fprintf(stderr, "%s\n", ctx->error_message); goto fail; } if (ctx->result_message) { d_fprintf(stdout, "%s\n", ctx->result_message); } /* fetch builtin */ ctx->domain_sid = sid_dup_talloc(mem_ctx, &global_sid_Builtin); ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid); status = libnet_samsync(SAM_DATABASE_BUILTIN, ctx); if (!NT_STATUS_IS_OK(status) && ctx->error_message) { d_fprintf(stderr, "%s\n", ctx->error_message); goto fail; } if (ctx->result_message) { d_fprintf(stdout, "%s\n", ctx->result_message); } fail: TALLOC_FREE(ctx); return status; }
NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info, uint8_t pipe_session_key[16], struct netr_SamInfo3 *sam3) { struct samu *sampw; DOM_GID *gids = NULL; const DOM_SID *user_sid = NULL; const DOM_SID *group_sid = NULL; DOM_SID domain_sid; uint32 user_rid, group_rid; NTSTATUS status; int num_gids = 0; const char *my_name; struct netr_UserSessionKey user_session_key; struct netr_LMSessionKey lm_session_key; NTTIME last_logon, last_logoff, acct_expiry, last_password_change; NTTIME allow_password_change, force_password_change; struct samr_RidWithAttributeArray groups; int i; struct dom_sid2 *sid = NULL; ZERO_STRUCT(user_session_key); ZERO_STRUCT(lm_session_key); sampw = server_info->sam_account; user_sid = pdb_get_user_sid(sampw); group_sid = pdb_get_group_sid(sampw); if ((user_sid == NULL) || (group_sid == NULL)) { DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n")); return NT_STATUS_UNSUCCESSFUL; } sid_copy(&domain_sid, user_sid); sid_split_rid(&domain_sid, &user_rid); sid = sid_dup_talloc(sam3, &domain_sid); if (!sid) { return NT_STATUS_NO_MEMORY; } if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) { DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid " "%s\n but group sid %s.\n" "The conflicting domain portions are not " "supported for NETLOGON calls\n", pdb_get_domain(sampw), pdb_get_username(sampw), sid_string_dbg(user_sid), sid_string_dbg(group_sid))); return NT_STATUS_UNSUCCESSFUL; } if(server_info->login_server) { my_name = server_info->login_server; } else { my_name = global_myname(); } status = nt_token_to_group_list(sam3, &domain_sid, server_info->num_sids, server_info->sids, &num_gids, &gids); if (!NT_STATUS_IS_OK(status)) { return status; } if (server_info->user_session_key.length) { memcpy(user_session_key.key, server_info->user_session_key.data, MIN(sizeof(user_session_key.key), server_info->user_session_key.length)); SamOEMhash(user_session_key.key, pipe_session_key, 16); } if (server_info->lm_session_key.length) { memcpy(lm_session_key.key, server_info->lm_session_key.data, MIN(sizeof(lm_session_key.key), server_info->lm_session_key.length)); SamOEMhash(lm_session_key.key, pipe_session_key, 8); } groups.count = num_gids; groups.rids = TALLOC_ARRAY(sam3, struct samr_RidWithAttribute, groups.count); if (!groups.rids) { return NT_STATUS_NO_MEMORY; } for (i=0; i < groups.count; i++) { groups.rids[i].rid = gids[i].g_rid; groups.rids[i].attributes = gids[i].attr; } unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw)); unix_to_nt_time(&last_logoff, get_time_t_max()); unix_to_nt_time(&acct_expiry, get_time_t_max()); unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw)); unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw)); unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw)); init_netr_SamInfo3(sam3, last_logon, last_logoff, acct_expiry, last_password_change, allow_password_change, force_password_change, talloc_strdup(sam3, pdb_get_username(sampw)), talloc_strdup(sam3, pdb_get_fullname(sampw)), talloc_strdup(sam3, pdb_get_logon_script(sampw)), talloc_strdup(sam3, pdb_get_profile_path(sampw)), talloc_strdup(sam3, pdb_get_homedir(sampw)), talloc_strdup(sam3, pdb_get_dir_drive(sampw)), 0, /* logon_count */ 0, /* bad_password_count */ user_rid, group_rid, groups, NETLOGON_EXTRA_SIDS, user_session_key, my_name, talloc_strdup(sam3, pdb_get_domain(sampw)), sid, lm_session_key, pdb_get_acct_ctrl(sampw), 0, /* sidcount */ NULL); /* struct netr_SidAttr *sids */ ZERO_STRUCT(user_session_key); ZERO_STRUCT(lm_session_key); return NT_STATUS_OK; }
/* dump sam database via samsync rpc calls */ NTSTATUS rpc_vampire_internals(struct net_context *c, const DOM_SID *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result; struct samsync_context *ctx = NULL; if (!sid_equal(domain_sid, get_global_sam_sid())) { d_printf("Cannot import users from %s at this time, " "as the current domain:\n\t%s: %s\nconflicts " "with the remote domain\n\t%s: %s\n" "Perhaps you need to set: \n\n\tsecurity=user\n\t" "workgroup=%s\n\n in your smb.conf?\n", domain_name, get_global_sam_name(), sid_string_dbg(get_global_sam_sid()), domain_name, sid_string_dbg(domain_sid), domain_name); return NT_STATUS_UNSUCCESSFUL; } result = libnet_samsync_init_context(mem_ctx, domain_sid, &ctx); if (!NT_STATUS_IS_OK(result)) { return result; } ctx->mode = NET_SAMSYNC_MODE_FETCH_PASSDB; ctx->cli = pipe_hnd; ctx->ops = &libnet_samsync_passdb_ops; ctx->domain_name = domain_name; ctx->force_full_replication = c->opt_force_full_repl ? true : false; ctx->clean_old_entries = c->opt_clean_old_entries ? true : false; parse_samsync_partial_replication_objects(ctx, argc, argv, &ctx->single_object_replication, &ctx->objects, &ctx->num_objects); /* fetch domain */ result = libnet_samsync(SAM_DATABASE_DOMAIN, ctx); if (!NT_STATUS_IS_OK(result) && ctx->error_message) { d_fprintf(stderr, "%s\n", ctx->error_message); goto fail; } if (ctx->result_message) { d_fprintf(stdout, "%s\n", ctx->result_message); } /* fetch builtin */ ctx->domain_sid = sid_dup_talloc(mem_ctx, &global_sid_Builtin); ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid); result = libnet_samsync(SAM_DATABASE_BUILTIN, ctx); if (!NT_STATUS_IS_OK(result) && ctx->error_message) { d_fprintf(stderr, "%s\n", ctx->error_message); goto fail; } if (ctx->result_message) { d_fprintf(stdout, "%s\n", ctx->result_message); } fail: TALLOC_FREE(ctx); return result; }