summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-04-22 12:23:10 +0200
committerVolker Lendecke <vl@samba.org>2009-04-22 12:33:46 +0200
commit8bc88aae5d44e0a6bc6157745edc3a83bd740ff7 (patch)
treea9c202930f893157aa09aa8da31810daffe53bc6 /source3/rpc_server
parente7466d020722ff6da3e6dc29cf5fa621aa039f7e (diff)
downloadsamba-8bc88aae5d44e0a6bc6157745edc3a83bd740ff7.tar.gz
samba-8bc88aae5d44e0a6bc6157745edc3a83bd740ff7.tar.bz2
samba-8bc88aae5d44e0a6bc6157745edc3a83bd740ff7.zip
Move serverinfo_to_SamInfo3() to rpc_server/
Normally I hate moving around stuff, but this function is only called from the RPC server side and it pulls in passdb when trying to link in our rpc client routines. That seems unnecessary to me.
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index ffb7dde1c3..f2441619ac 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1480,3 +1480,190 @@ NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
*presult = result;
return NT_STATUS_OK;
}
+
+/*******************************************************************
+ gets a domain user's groups from their already-calculated NT_USER_TOKEN
+ ********************************************************************/
+
+static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ size_t num_sids,
+ const DOM_SID *sids,
+ int *numgroups,
+ struct samr_RidWithAttribute **pgids)
+{
+ int i;
+
+ *numgroups=0;
+ *pgids = NULL;
+
+ for (i=0; i<num_sids; i++) {
+ struct samr_RidWithAttribute gid;
+ if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
+ continue;
+ }
+ gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
+ SE_GROUP_ENABLED);
+ ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
+ gid, pgids, numgroups);
+ if (*pgids == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
+ already be initialized and is used as the talloc parent for its members.
+*****************************************************************************/
+
+NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
+ uint8_t *pipe_session_key,
+ size_t pipe_session_key_len,
+ struct netr_SamInfo3 *sam3)
+{
+ struct samu *sampw;
+ struct samr_RidWithAttribute *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 (pipe_session_key && pipe_session_key_len != 16) {
+ DEBUG(0,("serverinfo_to_SamInfo3: invalid "
+ "pipe_session_key_len[%zu] != 16\n",
+ pipe_session_key_len));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ 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));
+ if (pipe_session_key) {
+ arcfour_crypt(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));
+ if (pipe_session_key) {
+ arcfour_crypt(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].rid;
+ groups.rids[i].attributes = gids[i].attributes;
+ }
+
+ 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;
+}