[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[samba.git] / source / rpc_client / cli_samr.c
index fb95da97aefe23f2073339e743c4e772ed5c31bc..8eaf20aa1ec395dd92018b453990953276e7aec9 100644 (file)
@@ -8,7 +8,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -17,8 +17,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -360,7 +359,8 @@ NTSTATUS rpccli_samr_del_groupmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
 
 NTSTATUS rpccli_samr_query_userinfo(struct rpc_pipe_client *cli,
                                    TALLOC_CTX *mem_ctx,
-                                   POLICY_HND *user_pol, uint16 switch_value, 
+                                   const POLICY_HND *user_pol,
+                                   uint16 switch_value, 
                                    SAM_USERINFO_CTR **ctr)
 {
        prs_struct qbuf, rbuf;
@@ -553,10 +553,14 @@ NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
-       sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
-       if (sid_ptrs == NULL)
-               return NT_STATUS_NO_MEMORY;
-
+       if (num_sids) {
+               sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
+               if (sid_ptrs == NULL)
+                       return NT_STATUS_NO_MEMORY;
+       } else {
+               sid_ptrs = NULL;
+       }
+       
        for (i=0; i<num_sids; i++)
                sid_ptrs[i] = 1;
 
@@ -639,7 +643,7 @@ NTSTATUS rpccli_samr_query_groupmem(struct rpc_pipe_client *cli,
  **/
 
 NTSTATUS rpccli_samr_enum_dom_users(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
+                                 POLICY_HND *pol, uint32 *start_idx, uint32 acb_mask,
                                  uint32 size, char ***dom_users, uint32 **rids,
                                  uint32 *num_dom_users)
 {
@@ -660,7 +664,7 @@ NTSTATUS rpccli_samr_enum_dom_users(struct rpc_pipe_client *cli, TALLOC_CTX *mem
        
        /* Fill query structure with parameters */
 
-       init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
+       init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, size);
        
        CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ENUM_DOM_USERS,
                q, r,
@@ -697,7 +701,7 @@ NTSTATUS rpccli_samr_enum_dom_users(struct rpc_pipe_client *cli, TALLOC_CTX *mem
                        fstring conv_buf;
                        
                        (*rids)[i] = r.sam[i].rid;
-                       unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
+                       unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf));
                        (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
                }
        }
@@ -765,7 +769,7 @@ NTSTATUS rpccli_samr_enum_dom_groups(struct rpc_pipe_client *cli,
                if (r.sam[i].hdr_name.buffer) {
                        unistr2_to_ascii((*dom_groups)[i].acct_name,
                                         &r.uni_grp_name[name_idx],
-                                        sizeof(fstring) - 1);
+                                        sizeof((*dom_groups)[i].acct_name));
                        name_idx++;
                }
 
@@ -836,7 +840,7 @@ NTSTATUS rpccli_samr_enum_als_groups(struct rpc_pipe_client *cli,
                if (r.sam[i].hdr_name.buffer) {
                        unistr2_to_ascii((*dom_aliases)[i].acct_name,
                                         &r.uni_grp_name[name_idx],
-                                        sizeof(fstring) - 1);
+                                        sizeof((*dom_aliases)[i].acct_name));
                        name_idx++;
                }
 
@@ -1101,15 +1105,97 @@ NTSTATUS rpccli_samr_query_dom_info(struct rpc_pipe_client *cli,
 
        /* Marshall data and send request */
 
-       init_samr_q_query_dom_info(&q, domain_pol, switch_value);
+       init_samr_q_query_domain_info(&q, domain_pol, switch_value);
 
        r.ctr = ctr;
 
        CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_DOMAIN_INFO,
                q, r,
                qbuf, rbuf,
-               samr_io_q_query_dom_info,
-               samr_io_r_query_dom_info,
+               samr_io_q_query_domain_info,
+               samr_io_r_query_domain_info,
+               NT_STATUS_UNSUCCESSFUL); 
+
+       /* Return output parameters */
+
+       if (!NT_STATUS_IS_OK(result = r.status)) {
+               goto done;
+       }
+
+ done:
+
+       return result;
+}
+
+/* Query domain info2 */
+
+NTSTATUS rpccli_samr_query_dom_info2(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx, 
+                                    POLICY_HND *domain_pol,
+                                    uint16 switch_value,
+                                    SAM_UNK_CTR *ctr)
+{
+       prs_struct qbuf, rbuf;
+       SAMR_Q_QUERY_DOMAIN_INFO2 q;
+       SAMR_R_QUERY_DOMAIN_INFO2 r;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DEBUG(10,("cli_samr_query_dom_info2\n"));
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Marshall data and send request */
+
+       init_samr_q_query_domain_info2(&q, domain_pol, switch_value);
+
+       r.ctr = ctr;
+
+       CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_DOMAIN_INFO2,
+               q, r,
+               qbuf, rbuf,
+               samr_io_q_query_domain_info2,
+               samr_io_r_query_domain_info2,
+               NT_STATUS_UNSUCCESSFUL); 
+
+       /* Return output parameters */
+
+       if (!NT_STATUS_IS_OK(result = r.status)) {
+               goto done;
+       }
+
+ done:
+
+       return result;
+}
+
+/* Set domain info */
+
+NTSTATUS rpccli_samr_set_domain_info(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx, 
+                                    POLICY_HND *domain_pol,
+                                    uint16 switch_value,
+                                    SAM_UNK_CTR *ctr)
+{
+       prs_struct qbuf, rbuf;
+       SAMR_Q_SET_DOMAIN_INFO q;
+       SAMR_R_SET_DOMAIN_INFO r;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DEBUG(10,("cli_samr_set_domain_info\n"));
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Marshall data and send request */
+
+       init_samr_q_set_domain_info(&q, domain_pol, switch_value, ctr);
+
+       CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_DOMAIN_INFO,
+               q, r,
+               qbuf, rbuf,
+               samr_io_q_set_domain_info,
+               samr_io_r_set_domain_info,
                NT_STATUS_UNSUCCESSFUL); 
 
        /* Return output parameters */
@@ -1205,6 +1291,55 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
        return result;
 }
 
+/* User change password given blobs */
+
+NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
+                                   TALLOC_CTX *mem_ctx, 
+                                   const char *username, 
+                                   DATA_BLOB new_nt_password,
+                                   DATA_BLOB old_nt_hash_enc,
+                                   DATA_BLOB new_lm_password,
+                                   DATA_BLOB old_lm_hash_enc)
+{
+       prs_struct qbuf, rbuf;
+       SAMR_Q_CHGPASSWD_USER q;
+       SAMR_R_CHGPASSWD_USER r;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
+
+       DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Marshall data and send request */
+
+       init_samr_q_chgpasswd_user(&q, srv_name_slash, username, 
+                                  new_nt_password.data, 
+                                  old_nt_hash_enc.data, 
+                                  new_lm_password.data,
+                                  old_lm_hash_enc.data);
+
+       CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD_USER,
+               q, r,
+               qbuf, rbuf,
+               samr_io_q_chgpasswd_user,
+               samr_io_r_chgpasswd_user,
+               NT_STATUS_UNSUCCESSFUL); 
+
+       /* Return output parameters */
+
+       if (!NT_STATUS_IS_OK(result = r.status)) {
+               goto done;
+       }
+
+ done:
+
+       return result;
+}
+
+
 /* change password 3 */
 
 NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
@@ -1212,13 +1347,12 @@ NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
                                const char *username, 
                                const char *newpassword, 
                                const char *oldpassword,
-                               SAM_UNK_INFO_1 **info,
-                               SAMR_CHANGE_REJECT **reject)
+                               SAM_UNK_INFO_1 *info,
+                               SAMR_CHANGE_REJECT *reject)
 {
        prs_struct qbuf, rbuf;
-       SAMR_Q_CHGPASSWD3 q;
-       SAMR_R_CHGPASSWD3 r;
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       SAMR_Q_CHGPASSWD_USER3 q;
+       SAMR_R_CHGPASSWD_USER3 r;
 
        uchar new_nt_password[516];
        uchar new_lm_password[516];
@@ -1232,14 +1366,11 @@ NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
 
        char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
 
-       DEBUG(10,("rpccli_samr_chgpasswd3\n"));
+       DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
-       *info = NULL;
-       *reject = NULL;
-
        /* Calculate the MD4 hash (NT compatible) of the password */
        E_md4hash(oldpassword, old_nt_hash);
        E_md4hash(newpassword, new_nt_hash);
@@ -1268,30 +1399,24 @@ NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
 
        /* Marshall data and send request */
 
-       init_samr_q_chgpasswd3(&q, srv_name_slash, username, 
-                              new_nt_password, 
-                              old_nt_hash_enc, 
-                              new_lm_password,
-                              old_lanman_hash_enc);
+       init_samr_q_chgpasswd_user3(&q, srv_name_slash, username, 
+                                   new_nt_password, 
+                                   old_nt_hash_enc, 
+                                   new_lm_password,
+                                   old_lanman_hash_enc);
+       r.info = info;
+       r.reject = reject;
 
-       CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD3,
+       CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD_USER3,
                q, r,
                qbuf, rbuf,
-               samr_io_q_chgpasswd3,
-               samr_io_r_chgpasswd3,
+               samr_io_q_chgpasswd_user3,
+               samr_io_r_chgpasswd_user3,
                NT_STATUS_UNSUCCESSFUL); 
 
        /* Return output parameters */
 
-       if (!NT_STATUS_IS_OK(result = r.status)) {
-               *info = &r.info;
-               *reject = &r.reject;
-               goto done;
-       }
-
- done:
-
-       return result;
+       return r.status;
 }
 
 /* This function returns the bizzare set of (max_entries, max_size) required
@@ -1432,10 +1557,16 @@ NTSTATUS rpccli_samr_lookup_rids(struct rpc_pipe_client *cli,
        *names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1);
        *name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1);
 
+       if ((*names == NULL) || (*name_types == NULL)) {
+               TALLOC_FREE(*names);
+               TALLOC_FREE(*name_types);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        for (i = 0; i < r.num_names1; i++) {
                fstring tmp;
 
-               unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
+               unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp));
                (*names)[i] = talloc_strdup(mem_ctx, tmp);
                (*name_types)[i] = r.type[i];
        }
@@ -1491,6 +1622,12 @@ NTSTATUS rpccli_samr_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
        *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
        *rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
 
+       if ((*rids == NULL) || (*rid_types == NULL)) {
+               TALLOC_FREE(*rids);
+               TALLOC_FREE(*rid_types);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        for (i = 0; i < r.num_rids1; i++) {
                (*rids)[i] = r.rids[i];
                (*rid_types)[i] = r.types[i];
@@ -1549,7 +1686,7 @@ NTSTATUS rpccli_samr_create_dom_user(struct rpc_pipe_client *cli, TALLOC_CTX *me
 /* Set userinfo */
 
 NTSTATUS rpccli_samr_set_userinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
-                               POLICY_HND *user_pol, uint16 switch_value,
+                               const POLICY_HND *user_pol, uint16 switch_value,
                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
@@ -1600,7 +1737,7 @@ NTSTATUS rpccli_samr_set_userinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
 /* Set userinfo2 */
 
 NTSTATUS rpccli_samr_set_userinfo2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
-                                POLICY_HND *user_pol, uint16 switch_value,
+                                  const POLICY_HND *user_pol, uint16 switch_value,
                                 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
@@ -1777,7 +1914,7 @@ NTSTATUS rpccli_samr_remove_sid_foreign_domain(struct rpc_pipe_client *cli,
 /* Query user security object */
 
 NTSTATUS rpccli_samr_query_sec_obj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *user_pol, uint16 switch_value
+                                 POLICY_HND *user_pol, uint32 sec_info
                                  TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
 {
        prs_struct qbuf, rbuf;
@@ -1792,7 +1929,7 @@ NTSTATUS rpccli_samr_query_sec_obj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_
 
        /* Marshall data and send request */
 
-       init_samr_q_query_sec_obj(&q, user_pol, switch_value);
+       init_samr_q_query_sec_obj(&q, user_pol, sec_info);
 
        CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_SEC_OBJECT,
                q, r,
@@ -1809,6 +1946,41 @@ NTSTATUS rpccli_samr_query_sec_obj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_
        return result;
 }
 
+/* Set user security object */
+
+NTSTATUS rpccli_samr_set_sec_obj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+                                 POLICY_HND *user_pol, uint32 sec_info, 
+                                 SEC_DESC_BUF *sec_desc_buf)
+{
+       prs_struct qbuf, rbuf;
+       SAMR_Q_SET_SEC_OBJ q;
+       SAMR_R_SET_SEC_OBJ r;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DEBUG(10,("cli_samr_set_sec_obj\n"));
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Marshall data and send request */
+
+       init_samr_q_set_sec_obj(&q, user_pol, sec_info, sec_desc_buf);
+
+       CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_SEC_OBJECT,
+               q, r,
+               qbuf, rbuf,
+               samr_io_q_set_sec_obj,
+               samr_io_r_set_sec_obj,
+               NT_STATUS_UNSUCCESSFUL); 
+
+       /* Return output parameters */
+
+       result = r.status;
+
+       return result;
+}
+
+
 /* Get domain password info */
 
 NTSTATUS rpccli_samr_get_dom_pwinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
@@ -1849,6 +2021,50 @@ NTSTATUS rpccli_samr_get_dom_pwinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem
        return result;
 }
 
+/* Get domain password info */
+
+NTSTATUS rpccli_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+                                      POLICY_HND *pol, uint16 *min_pwd_length, 
+                                      uint32 *password_properties, uint32 *unknown1)
+{
+       prs_struct qbuf, rbuf;
+       SAMR_Q_GET_USRDOM_PWINFO q;
+       SAMR_R_GET_USRDOM_PWINFO r;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DEBUG(10,("cli_samr_get_usrdom_pwinfo\n"));
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Marshall data and send request */
+
+       init_samr_q_get_usrdom_pwinfo(&q, pol);
+
+       CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_GET_USRDOM_PWINFO,
+                  q, r,
+                  qbuf, rbuf,
+                  samr_io_q_get_usrdom_pwinfo,
+                  samr_io_r_get_usrdom_pwinfo,
+                  NT_STATUS_UNSUCCESSFUL); 
+
+       /* Return output parameters */
+
+       result = r.status;
+
+       if (NT_STATUS_IS_OK(result)) {
+               if (min_pwd_length)
+                       *min_pwd_length = r.min_pwd_length;
+               if (password_properties)
+                       *password_properties = r.password_properties;
+               if (unknown1)
+                       *unknown1 = r.unknown_1;
+       }
+
+       return result;
+}
+
+
 /* Lookup Domain Name */
 
 NTSTATUS rpccli_samr_lookup_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,