s3-lsa: Add and remove trusted domain account
authorSumit Bose <sbose@redhat.com>
Mon, 30 Aug 2010 16:09:12 +0000 (18:09 +0200)
committerGünther Deschner <gd@samba.org>
Wed, 16 Feb 2011 10:44:06 +0000 (11:44 +0100)
Signed-off-by: Günther Deschner <gd@samba.org>
source3/rpc_server/lsa/srv_lsa_nt.c

index ed9ee8bb6f257f8af1a8f33ba63f6ee58164cad5..d215085ddf7380d47e5e3b62333c6c72011bb540 100644 (file)
@@ -1598,6 +1598,78 @@ NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
                                           r->out.trustdom_handle);
 }
 
+static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
+                                       const char *netbios_name,
+                                       struct trustDomainPasswords auth_struct)
+{
+       NTSTATUS status;
+       struct samu *sam_acct;
+       char *acct_name;
+       uint32_t rid;
+       struct dom_sid user_sid;
+       int i;
+       char *dummy;
+       size_t dummy_size;
+
+       sam_acct = samu_new(mem_ctx);
+       if (sam_acct == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
+       if (acct_name == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!pdb_set_domain(sam_acct, get_global_sam_name(), PDB_SET)) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!pdb_new_rid(&rid)) {
+               return NT_STATUS_DS_NO_MORE_RIDS;
+       }
+       sid_compose(&user_sid, get_global_sam_sid(), rid);
+       if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       for (i = 0; i < auth_struct.incoming.count; i++) {
+               switch (auth_struct.incoming.current.array[i].AuthType) {
+                       case TRUST_AUTH_TYPE_CLEAR:
+                               if (!convert_string_talloc(mem_ctx,
+                                                          CH_UTF16LE,
+                                                          CH_UNIX,
+                                                          auth_struct.incoming.current.array[i].AuthInfo.clear.password,
+                                                          auth_struct.incoming.current.array[i].AuthInfo.clear.size,
+                                                          &dummy,
+                                                          &dummy_size,
+                                                          false)) {
+                                       return NT_STATUS_UNSUCCESSFUL;
+                               }
+                               if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
+                                       return NT_STATUS_UNSUCCESSFUL;
+                               }
+                               break;
+                       default:
+                               continue;
+               }
+       }
+
+       status = pdb_add_sam_account(sam_acct);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return NT_STATUS_OK;
+}
+
 /***************************************************************************
  _lsa_CreateTrustedDomainEx2
  ***************************************************************************/
@@ -1711,6 +1783,15 @@ NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
                return status;
        }
 
+       if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
+               status = add_trusted_domain_user(p->mem_ctx,
+                                                r->in.info->netbios_name.string,
+                                                auth_struct);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
        status = create_lsa_policy_handle(p->mem_ctx, p,
                                          LSA_HANDLE_TRUST_TYPE,
                                          acc_granted,
@@ -1782,7 +1863,9 @@ NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
 {
        NTSTATUS status;
        struct lsa_info *handle;
-       struct trustdom_info *info;
+       struct pdb_trusted_domain *td;
+       struct samu *sam_acct;
+       char *acct_name;
 
        /* find the connection policy handle. */
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
@@ -1797,14 +1880,37 @@ NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
-                                                 r->in.dom_sid,
-                                                 &info);
+       status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       status = pdb_del_trusted_domain(info->name);
+       if (td->netbios_name == NULL || *td->netbios_name == '\0') {
+               DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
+                          sid_string_tos(r->in.dom_sid)));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
+               sam_acct = samu_new(p->mem_ctx);
+               if (sam_acct == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
+               if (acct_name == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+               status = pdb_delete_sam_account(sam_acct);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
+       status = pdb_del_trusted_domain(td->netbios_name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }