]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:rpc_server: Implement SAMR SetUserInfo(2) level 32
authorAndreas Schneider <asn@samba.org>
Tue, 24 Aug 2021 13:00:37 +0000 (15:00 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 28 Jul 2022 11:51:29 +0000 (11:51 +0000)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/rpc_server/samr/srv_samr_nt.c
source3/rpc_server/samr/srv_samr_util.c
source3/rpc_server/samr/srv_samr_util.h

index b285dcbeea21c2acede01065518c3d9db8da4e2f..ee92014f7621e6a8cfc2e7164a040f7311cb0142 100644 (file)
@@ -5240,6 +5240,63 @@ static NTSTATUS set_user_info_31(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS set_user_info_32(TALLOC_CTX *mem_ctx,
+                                const char *rhost,
+                                DATA_BLOB *pw_data,
+                                struct samr_UserInfo32 *id32,
+                                struct samu *pwd)
+{
+       NTSTATUS status;
+       bool ok;
+
+       if (pw_data->length == 0 || pw_data->length > 514) {
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       if (id32 == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (id32->info.fields_present == 0) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (id32->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       if ((id32->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
+           (id32->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
+               ok = set_user_info_pw_aes(pw_data, rhost, pwd);
+               if (!ok) {
+                       return NT_STATUS_WRONG_PASSWORD;
+               }
+       }
+
+       copy_id32_to_sam_passwd(pwd, id32);
+
+       status = pdb_update_sam_account(pwd);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /*
+        * We need to "pdb_update_sam_account" before the unix primary group
+        * is set, because the idealx scripts would also change the
+        * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
+        * the delete explicit / add explicit, which would then fail to find
+        * the previous primaryGroupSid value.
+        */
+       if (IS_SAM_CHANGED(pwd, PDB_GROUPSID)) {
+               status = pdb_set_unix_primary_group(mem_ctx, pwd);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
 /*************************************************************
 **************************************************************/
 
@@ -5423,6 +5480,11 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
        case 31: /* UserInternal5InformationNew */
                acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
                break;
+       case 32:
+               fields = info->info32.info.fields_present;
+               acc_required =
+                       samr_set_user_info_map_fields_to_access_mask(fields);
+               break;
        default:
                return NT_STATUS_INVALID_INFO_CLASS;
        }
@@ -5749,6 +5811,46 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 
                        break;
                }
+               case 32: {
+                       DATA_BLOB new_password = data_blob_null;
+                       const DATA_BLOB ciphertext = data_blob_const(
+                               info->info32.password.cipher,
+                               info->info32.password.cipher_len);
+                       DATA_BLOB iv = data_blob_const(
+                               info->info32.password.salt,
+                               sizeof(info->info32.password.salt));
+
+                       status = session_extract_session_key(session_info,
+                                                            &session_key,
+                                                            KEY_USE_16BYTES);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               break;
+                       }
+
+                       status =
+                               samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
+                                       p->mem_ctx,
+                                       &ciphertext,
+                                       &session_key,
+                                       &samr_aes256_enc_key_salt,
+                                       &samr_aes256_mac_key_salt,
+                                       &iv,
+                                       info->info32.password.auth_data,
+                                       &new_password);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               status = NT_STATUS_WRONG_PASSWORD;
+                               break;
+                       }
+
+                       status = set_user_info_32(p->mem_ctx,
+                                                 rhost,
+                                                 &new_password,
+                                                 &info->info32,
+                                                 pwd);
+                       data_blob_clear_free(&new_password);
+
+                       break;
+               }
                default:
                        status = NT_STATUS_INVALID_INFO_CLASS;
        }
index d3bd3c71ccd3710a6154f5a951cdf5741b6d713d..fa35ce6a5de708895944273d845a855ac0df0022 100644 (file)
@@ -731,6 +731,15 @@ void copy_id25_to_sam_passwd(struct samu *to,
        copy_id21_to_sam_passwd("INFO_25", to, &from->info);
 }
 
+void copy_id32_to_sam_passwd(struct samu *to, struct samr_UserInfo32 *from)
+{
+       if (from == NULL || to == NULL) {
+               return;
+       }
+
+       copy_id21_to_sam_passwd("INFO_32", to, &from->info);
+}
+
 void copy_pwd_expired_to_sam_passwd(struct samu *to,
                                    uint8_t password_expired)
 {
index bf38217052a2470ce81eb6bfb004bdf9dc4c24d6..475e2c3728dd7186c01d3b84e0363251080b9626 100644 (file)
@@ -61,6 +61,7 @@ void copy_id24_to_sam_passwd(struct samu *to,
                             struct samr_UserInfo24 *from);
 void copy_id25_to_sam_passwd(struct samu *to,
                             struct samr_UserInfo25 *from);
+void copy_id32_to_sam_passwd(struct samu *to, struct samr_UserInfo32 *from);
 void copy_pwd_expired_to_sam_passwd(struct samu *to,
                                    uint8_t password_expired);