fixed samr_create_user(). we now correctly parse the query and the reply.
authorJean-François Micouleau <jfm@samba.org>
Thu, 28 Sep 2000 17:35:03 +0000 (17:35 +0000)
committerJean-François Micouleau <jfm@samba.org>
Thu, 28 Sep 2000 17:35:03 +0000 (17:35 +0000)
And we create the disabled account. That means we can create user and
trust accounts remotely !

ifdef out a return in passdb/smbpass.c. I think I didn't break any
security. Jeremy could you check if I didn't make any mistakes ???

J.F.
(This used to be commit 416be1b64f366c8b859f25856fce2467ec0446d9)

source3/include/rpc_samr_old.h
source3/passdb/smbpass.c
source3/passdb/smbpasschange.c
source3/rpc_parse/parse_samr.c
source3/rpc_server/srv_samr.c

index d385f18e76b04d7498d86ab2d48c2dc01917cca6..620f5bc628752b21ef50edba4bd18b4779b01537 100644 (file)
@@ -991,9 +991,8 @@ typedef struct q_samr_create_user_info
        UNIHDR  hdr_mach_acct;       /* unicode machine account name header */
        UNISTR2 uni_mach_acct;       /* unicode machine account name */
 
-       uint32 acct_ctrl;            /* 32 bit ACB_XXXX */
-       uint16 unknown_1;            /* 16 bit unknown - 0x00B0 */
-       uint16 unknown_2;            /* 16 bit unknown - 0xe005 */
+       uint32 acb_info;            /* 32 bit ACB_XXXX */
+       uint32 access_mask;         /* 0xe005 00b0 */
 
 } SAMR_Q_CREATE_USER;
 
@@ -1003,9 +1002,8 @@ typedef struct r_samr_create_user_info
 {
        POLICY_HND pol;       /* policy handle */
 
-       /* rid4.unknown - fail: 0030 success: 0x03ff */
-       DOM_RID4 rid4;         /* rid and attributes */
-
+       uint32 unknown_0;     /* 0x0007 03ff */
+       uint32 user_rid;      /* user RID */
        uint32 status;         /* return status - fail: 0xC000 0099: user exists */
 
 } SAMR_R_CREATE_USER;
index ec1a984b76bbd716dfd5989ca62ded286e7bcf89..45935db99ee8db4fcff5d354d19f8f8630e2b598 100644 (file)
@@ -329,7 +329,13 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
       pw_buf.smb_nt_passwd = NULL;
       pw_buf.smb_passwd = NULL;
       pw_buf.acct_ctrl |= ACB_DISABLED;
+
+#if 0 /* JFM */
+       /* commented to continue in the case of a trust account disabled */
+       /* samr_create_user() is adding disabled accounts */
+
       return &pw_buf;
+#endif
     }
 
     if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
index 2c971fbff963e5d72a8a9ccc8137357c940c1c24..0c30bbe4a5697c3942f63c3d1496971c13c9e1a8 100644 (file)
@@ -41,7 +41,9 @@ static BOOL add_new_user(char *user_name, uid_t uid, int local_flags,
        
        if(local_flags & LOCAL_DISABLE_USER) {
                new_smb_pwent.acct_ctrl |= ACB_DISABLED;
-       } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
+       }
+       
+       if (local_flags & LOCAL_SET_NO_PASSWORD) {
                new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
        } else {
                new_smb_pwent.smb_passwd = new_p16;
index 72e803d22beea572c7ed697f4140a451a70b1d41..ce26ad454f5187677358dd2428a90740d56863c4 100644 (file)
@@ -3082,11 +3082,9 @@ BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps,
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("acct_ctrl", ps, depth, &q_u->acct_ctrl))
+       if(!prs_uint32("acb_info", ps, depth, &q_u->acb_info))
                return False;
-       if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
-               return False;
-       if(!prs_uint16("unknown_2", ps, depth, &q_u->unknown_2))
+       if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
                return False;
 
        return True;
@@ -3109,7 +3107,10 @@ BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER *r_u, prs_struct *ps,
 
        if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
                return False;
-       if(!prs_align(ps))
+
+       if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
+               return False;
+       if(!prs_uint32("user_rid", ps, depth, &r_u->user_rid))
                return False;
 
        if(!prs_uint32("status", ps, depth, &r_u->status))
index ab32bfe5636a4af4b60b0423358fa0ee5bc06c94..2ef29df990638565979129edba8f29a3eb8896a9 100644 (file)
@@ -1826,26 +1826,38 @@ static BOOL api_samr_query_dom_info(pipes_struct *p)
        return True;
 }
 
+
 /*******************************************************************
  api_samr_create_user
  ********************************************************************/
 static BOOL api_samr_create_user(pipes_struct *p)
 {
-       uint32 status = 0;
        struct sam_passwd *sam_pass;
        fstring mach_acct;
+       pstring err_str;
+       pstring msg_str;
+       int local_flags=0;
+       
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
-       int i;
 
        SAMR_Q_CREATE_USER q_u;
        SAMR_R_CREATE_USER r_u;
 
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
        DEBUG(5,("api_samr_create_user: %d\n", __LINE__));
 
        /* grab the samr create user */
        samr_io_q_create_user("", &q_u, data, 0);
 
+       /* find the policy handle.  open a policy on it. */
+       if ((find_lsa_policy_by_hnd(&q_u.pol) == -1)) {
+               r_u.status = NT_STATUS_INVALID_HANDLE;
+               goto out;
+       }
+
        /* find the machine account: tell the caller if it exists.
           lkclXXXX i have *no* idea if this is a problem or not
           or even if you are supposed to construct a different
@@ -1853,31 +1865,58 @@ static BOOL api_samr_create_user(pipes_struct *p)
         */
 
        fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer, q_u.uni_mach_acct.uni_str_len));
+       strlower(mach_acct);
 
        become_root();
        sam_pass = getsam21pwnam(mach_acct);
        unbecome_root();
-
        if (sam_pass != NULL) {
                /* machine account exists: say so */
-               status = 0xC0000000 | NT_STATUS_USER_EXISTS;
-       } else {
-               /* this could cause trouble... */
-               DEBUG(0,("trouble!\n"));
-               status = 0;
+               r_u.status = NT_STATUS_USER_EXISTS;
+               goto out;
        }
 
-       /* set up the SAMR create_user response */
-       memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
-       if (status == 0) {
-               for (i = 4; i < POL_HND_SIZE; i++) {
-                       r_u.pol.data[i] = i+1;
-               }
+       /* get a (unique) handle.  open a policy on it. */
+       if (!open_lsa_policy_hnd(&r_u.pol)) {
+               r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto out;
+       }
+
+       local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
+       local_flags|= (q_u.acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
+
+       if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
+               DEBUG(0, ("%s\n", err_str));
+               r_u.status = NT_STATUS_ACCESS_DENIED;
+               close_lsa_policy_hnd(&r_u.pol);
+               memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+               goto out;
+       }
+
+       become_root();
+       sam_pass = getsam21pwnam(mach_acct);
+       unbecome_root();
+       if (sam_pass == NULL) {
+               /* account doesn't exist: say so */
+               r_u.status = NT_STATUS_ACCESS_DENIED;
+               close_lsa_policy_hnd(&r_u.pol);
+               memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+               goto out;
+       }
+
+       /* associate the RID with the (unique) handle. */
+       if (!set_lsa_policy_samr_rid(&r_u.pol, sam_pass->user_rid)) {
+               /* oh, whoops.  don't know what error message to return, here */
+               r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               close_lsa_policy_hnd(&r_u.pol);
+               memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+               goto out;
        }
 
-       init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
-       r_u.status    = status;
+       r_u.unknown_0=0x000703ff;
+       r_u.user_rid=sam_pass->user_rid;
 
+ out:  
        /* store the response in the SMB stream */
        if(!samr_io_r_create_user("", &r_u, rdata, 0))
                return False;