summaryrefslogtreecommitdiff
path: root/source3/auth/auth_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/auth/auth_util.c')
-rw-r--r--source3/auth/auth_util.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index ce47e94eb5..6efd31d574 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -1654,6 +1654,239 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+/*****************************************************************************
+ Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
+******************************************************************************/
+
+NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
+ const char *sent_nt_username,
+ const char *domain,
+ const struct wbcAuthUserInfo *info,
+ auth_serversupplied_info **server_info)
+{
+ char zeros[16];
+
+ NTSTATUS nt_status = NT_STATUS_OK;
+ char *found_username = NULL;
+ const char *nt_domain;
+ const char *nt_username;
+ struct samu *sam_account = NULL;
+ DOM_SID user_sid;
+ DOM_SID group_sid;
+ bool username_was_mapped;
+ uint32_t i;
+
+ uid_t uid = (uid_t)-1;
+ gid_t gid = (gid_t)-1;
+
+ auth_serversupplied_info *result;
+
+ result = make_server_info(NULL);
+ if (result == NULL) {
+ DEBUG(4, ("make_server_info failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /*
+ Here is where we should check the list of
+ trusted domains, and verify that the SID
+ matches.
+ */
+
+ memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
+ memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
+
+ if (info->account_name) {
+ nt_username = talloc_strdup(result, info->account_name);
+ } else {
+ /* If the server didn't give us one, just use the one we sent
+ * them */
+ nt_username = talloc_strdup(result, sent_nt_username);
+ }
+ if (!nt_username) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (info->domain_name) {
+ nt_domain = talloc_strdup(result, info->domain_name);
+ } else {
+ /* If the server didn't give us one, just use the one we sent
+ * them */
+ nt_domain = talloc_strdup(result, domain);
+ }
+ if (!nt_domain) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* try to fill the SAM account.. If getpwnam() fails, then try the
+ add user script (2.2.x behavior).
+
+ We use the _unmapped_ username here in an attempt to provide
+ consistent username mapping behavior between kerberos and NTLM[SSP]
+ authentication in domain mode security. I.E. Username mapping
+ should be applied to the fully qualified username
+ (e.g. DOMAIN\user) and not just the login name. Yes this means we
+ called map_username() unnecessarily in make_user_info_map() but
+ that is how the current code is designed. Making the change here
+ is the least disruptive place. -- jerry */
+
+ if ( !(sam_account = samu_new( result )) ) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* this call will try to create the user if necessary */
+
+ nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
+ &found_username, &uid, &gid, sam_account,
+ &username_was_mapped);
+
+ /* if we still don't have a valid unix account check for
+ 'map to guest = bad uid' */
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ TALLOC_FREE( result );
+ if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
+ make_server_info_guest(server_info);
+ return NT_STATUS_OK;
+ }
+ return nt_status;
+ }
+
+ if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_pass_last_set_time(
+ sam_account,
+ nt_time_to_unix(info->pass_last_set_time),
+ PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_pass_can_change_time(
+ sam_account,
+ nt_time_to_unix(info->pass_can_change_time),
+ PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_pass_must_change_time(
+ sam_account,
+ nt_time_to_unix(info->pass_must_change_time),
+ PDB_CHANGED)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* save this here to _net_sam_logon() doesn't fail (it assumes a
+ valid struct samu) */
+
+ result->sam_account = sam_account;
+ result->unix_name = talloc_strdup(result, found_username);
+
+ result->login_server = talloc_strdup(result, info->logon_server);
+
+ /* Fill in the unix info we found on the way */
+
+ result->uid = uid;
+ result->gid = gid;
+
+ /* Create a 'combined' list of all SIDs we might want in the SD */
+
+ result->num_sids = info->num_sids - 2;
+ result->sids = talloc_array(result, DOM_SID, result->num_sids);
+ if (result->sids == NULL) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i < result->num_sids; i++) {
+ memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
+ }
+
+ /* ensure we are never given NULL session keys */
+
+ ZERO_STRUCT(zeros);
+
+ if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
+ result->user_session_key = data_blob_null;
+ } else {
+ result->user_session_key = data_blob_talloc(
+ result, info->user_session_key,
+ sizeof(info->user_session_key));
+ }
+
+ if (memcmp(info->lm_session_key, zeros, 8) == 0) {
+ result->lm_session_key = data_blob_null;
+ } else {
+ result->lm_session_key = data_blob_talloc(
+ result, info->lm_session_key,
+ sizeof(info->lm_session_key));
+ }
+
+ result->was_mapped = username_was_mapped;
+
+ *server_info = result;
+
+ return NT_STATUS_OK;
+}
+
/***************************************************************************
Free a user_info struct
***************************************************************************/