diff -rub samba-3.0.24/source/utils/net_rpc.c samba-3.0.24-karma/source/utils/net_rpc.c --- samba-3.0.24/source/utils/net_rpc.c 2007-02-04 12:59:25.000000000 -0600 +++ samba-3.0.24-jmk/source/utils/net_rpc.c 2007-02-08 17:47:00.000000000 -0600 @@ -583,13 +583,22 @@ uint32 acb_info; uint32 unknown, user_rid; - if (argc < 1) { - d_printf("User must be specified\n"); + /* jmk/pmonkey mods to fix ability to set password */ + SAM_USERINFO_CTR ctr; + SAM_USER_INFO_24 p24; + SAM_USER_INFO_16 p16; + const char *acct_password; + uchar pwbuf[516]; + + if (argc != 2) { + d_printf("User and password must be specified\n"); rpc_user_usage(argc, argv); return NT_STATUS_OK; } acct_name = argv[0]; + acct_password = argv[1]; + /* jmk */ /* Get sam policy handle */ @@ -620,60 +629,53 @@ goto done; } - if (argc == 2) { - - uint32 *user_rids, num_rids, *name_types; - uint32 flags = 0x000003e8; /* Unknown */ - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_24 p24; - uchar pwbuf[516]; + /* jmk/pmonkey -- mod to set a password on the new account and enable the account */ + /* stolen 100% from the machine account joining code */ - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, - flags, 1, &acct_name, - &num_rids, &user_rids, - &name_types); + /* Open handle on user */ - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - user_rids[0], &user_pol); - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } + rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, + SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol); /* Set password on account */ + encode_pw_buffer(pwbuf, acct_password, STR_UNICODE); ZERO_STRUCT(ctr); ZERO_STRUCT(p24); - encode_pw_buffer(pwbuf, argv[1], STR_UNICODE); - init_sam_user_info24(&p24, (char *)pwbuf,24); ctr.switch_value = 24; ctr.info.id24 = &p24; - result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24, + rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24, &cli->user_session_key, &ctr); - if (!NT_STATUS_IS_OK(result)) { - d_fprintf(stderr, "Failed to set password for user %s - %s\n", - acct_name, nt_errstr(result)); + /* Why do we have to try to (re-)set the ACB to be the same as what + we passed in the samr_create_dom_user() call? When a NT + workstation is joined to a domain by an administrator the + acb_info is set to 0x80. For a normal user with "Add + workstations to the domain" rights the acb_info is 0x84. I'm + not sure whether it is supposed to make a difference or not. NT + seems to cope with either value so don't bomb out if the set + userinfo2 level 0x10 fails. -tpot */ - result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol); + ZERO_STRUCT(ctr); + ctr.switch_value = 16; + ctr.info.id16 = &p16; - if (!NT_STATUS_IS_OK(result)) { - d_fprintf(stderr, "Failed to delete user %s - %s\n", - acct_name, nt_errstr(result)); - return result; - } - } + init_sam_user_info16(&p16, acb_info); + + /* Ignoring the return value is necessary for joining a domain + as a normal user with "Add workstation to domain" privilege. */ + + result = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16, + &cli->user_session_key, &ctr); + + rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); + //cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ + /* jmk */ - } done: if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Failed to add user %s - %s\n", acct_name,