This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[jra/samba/.git] / source3 / utils / net_rpc_samsync.c
index af778fcc0a6ada6edf628f57ce017353270fba95..ac3b78fc7a2f6712c691164f6633e61363cf0bb8 100644 (file)
@@ -56,14 +56,23 @@ static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a)
 {
        fstring hex_nt_passwd, hex_lm_passwd;
        uchar lm_passwd[16], nt_passwd[16];
+       static uchar zero_buf[16];
 
-       /* Decode hashes from password hash */
-       sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0);
-       sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0);
+       /* Decode hashes from password hash (if they are not NULL) */
        
-       /* Encode as strings */
-       smbpasswd_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info);
-       smbpasswd_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info);
+       if (memcmp(a->pass.buf_lm_pwd, zero_buf, 16) != 0) {
+               sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0);
+               smbpasswd_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info);
+       } else {
+               smbpasswd_sethexpwd(hex_lm_passwd, NULL, 0);
+       }
+
+       if (memcmp(a->pass.buf_nt_pwd, zero_buf, 16) != 0) {
+               sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0);
+               smbpasswd_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info);
+       } else {
+               smbpasswd_sethexpwd(hex_nt_passwd, NULL, 0);
+       }
        
        printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name),
               a->user_rid, hex_lm_passwd, hex_nt_passwd,
@@ -111,7 +120,7 @@ static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta)
 
 static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds)
 {
-       unsigned last_rid = -1;
+       unsigned sync_context = 0;
         NTSTATUS result;
        int i;
         TALLOC_CTX *mem_ctx;
@@ -119,22 +128,22 @@ static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret
         SAM_DELTA_CTR *deltas;
         uint32 num_deltas;
 
-       if (!(mem_ctx = talloc_init())) {
+       if (!(mem_ctx = talloc_init("dump_database"))) {
                return;
        }
 
        d_printf("Dumping database %u\n", db_type);
 
        do {
-               result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, db_type, last_rid+1,
+               result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, db_type,
+                                              sync_context,
                                               &num_deltas, &hdr_deltas, &deltas);
                clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), ret_creds);
-               last_rid = 0;
                 for (i = 0; i < num_deltas; i++) {
                        display_sam_entry(&hdr_deltas[i], &deltas[i]);
-                       last_rid = hdr_deltas[i].target_rid;
                 }
-       } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
+               sync_context += 1;
+       } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 
        talloc_destroy(mem_ctx);
 }
@@ -162,7 +171,7 @@ int rpc_samdump(int argc, const char **argv)
        }
 
        if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL)) {
-               d_printf("Could not retrieve domain trust secret");
+               d_printf("Could not retrieve domain trust secret\n");
                goto fail;
        }
        
@@ -194,6 +203,7 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
 {
        fstring s;
        uchar lm_passwd[16], nt_passwd[16];
+       static uchar zero_buf[16];
 
        /* Username, fullname, home dir, dir drive, logon script, acct
           desc, workstations, profile. */
@@ -246,11 +256,20 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
 
        pdb_set_kickoff_time(account, get_time_t_max(), PDB_CHANGED);
 
-       /* Decode hashes from password hash */
-       sam_pwd_hash(delta->user_rid, delta->pass.buf_lm_pwd, lm_passwd, 0);
-       sam_pwd_hash(delta->user_rid, delta->pass.buf_nt_pwd, nt_passwd, 0);
-       pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED);
-       pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED);
+       /* Decode hashes from password hash 
+          Note that win2000 may send us all zeros for the hashes if it doesn't 
+          think this channel is secure enough - don't set the passwords at all
+          in that case
+        */
+       if (memcmp(delta->pass.buf_lm_pwd, zero_buf, 16) != 0) {
+               sam_pwd_hash(delta->user_rid, delta->pass.buf_lm_pwd, lm_passwd, 0);
+               pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED);
+       }
+
+       if (memcmp(delta->pass.buf_nt_pwd, zero_buf, 16) != 0) {
+               sam_pwd_hash(delta->user_rid, delta->pass.buf_nt_pwd, nt_passwd, 0);
+               pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED);
+       }
 
        /* TODO: account expiry time */
 
@@ -267,6 +286,8 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
        SAM_ACCOUNT *sam_account=NULL;
        GROUP_MAP map;
        struct group *grp;
+       DOM_SID sid;
+       BOOL try_add = False;
 
        fstrcpy(account, unistr2_static(&delta->uni_acct_name));
        d_printf("Creating account: %s\n", account);
@@ -275,10 +296,6 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
                return nt_ret;
 
        if (!pdb_getsampwnam(sam_account, account)) {
-               struct passwd *pw;
-
-               pdb_free_sam(&sam_account);
-
                /* Create appropriate user */
                if (delta->acb_info & ACB_NORMAL) {
                        pstrcpy(add_script, lp_adduser_script());
@@ -299,33 +316,30 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
                        DEBUG(1,("fetch_account: Running the command `%s' "
                                 "gave %d\n", add_script, add_ret));
                }
-               pw = getpwnam_alloc(account);
-               if (pw) {
-                       nt_ret = pdb_init_sam_pw(&sam_account, pw);
-
-                       if (!NT_STATUS_IS_OK(nt_ret)) {
-                               passwd_free(&pw);
-                               pdb_free_sam(&sam_account);
-                               return nt_ret;
-                       }
-                       passwd_free(&pw);
-               } else {
-                       DEBUG(3, ("Could not create account %s\n", account));
-                       pdb_free_sam(&sam_account);
-                       return NT_STATUS_NO_SUCH_USER;
+
+               if (!pdb_getsampwnam(sam_account, account)) {
+                       try_add = True;
+                       /* still not there, hope the backend likes NUAs */
                }
        }
 
        sam_account_from_delta(sam_account, delta);
 
-       if (!pdb_add_sam_account(sam_account)) {
-               DEBUG(1, ("SAM Account for %s already existed, updating\n",
-                         account));
-               pdb_update_sam_account(sam_account);
+       if (try_add) { 
+               if (!pdb_add_sam_account(sam_account)) {
+                       DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
+                                 account));
+               }
+       } else {
+               if (!pdb_update_sam_account(sam_account)) {
+                       DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
+                                 account));
+               }
        }
 
-       if (!get_group_map_from_sid(*pdb_get_group_sid(sam_account),
-                                   &map, False)) {
+       sid = *pdb_get_group_sid(sam_account);
+
+       if (!pdb_getgrsid(&map, sid, False)) {
                DEBUG(0, ("Primary group of %s has no mapping!\n",
                          pdb_get_username(sam_account)));
                pdb_free_sam(&sam_account);
@@ -333,7 +347,8 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
        }
 
        if (!(grp = getgrgid(map.gid))) {
-               DEBUG(0, ("Could not find unix group %d\n", map.gid));
+               DEBUG(0, ("Could not find unix group %d for user %s (group SID=%s)\n", 
+                         map.gid, pdb_get_username(sam_account), sid_string_static(&sid)));
                pdb_free_sam(&sam_account);
                return NT_STATUS_NO_SUCH_GROUP;
        }
@@ -353,7 +368,7 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
        DOM_SID group_sid;
        fstring sid_string;
        GROUP_MAP map;
-       int flag = TDB_INSERT;
+       BOOL insert = True;
 
        unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)-1);
        unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)-1);
@@ -363,9 +378,9 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
        sid_append_rid(&group_sid, rid);
        sid_to_string(sid_string, &group_sid);
 
-       if (get_group_map_from_sid(group_sid, &map, False)) {
+       if (pdb_getgrsid(&map, group_sid, False)) {
                grp = getgrgid(map.gid);
-               flag = 0; /* Don't TDB_INSERT, mapping exists */
+               insert = False;
        }
 
        if (grp == NULL)
@@ -392,7 +407,10 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
        map.priv_set.count = 0;
        map.priv_set.set = NULL;
 
-       add_mapping_entry(&map, flag);
+       if (insert)
+               pdb_add_group_mapping_entry(&map);
+       else
+               pdb_update_group_mapping_entry(&map);
 
        return NT_STATUS_OK;
 }
@@ -427,7 +445,7 @@ fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta)
 
        d_printf("Group members of %s: ", grp->gr_name);
 
-       if (!(t = talloc_init())) {
+       if (!(t = talloc_init("fetch_group_mem_info"))) {
                DEBUG(0, ("could not talloc_init\n"));
                return NT_STATUS_NO_MEMORY;
        }
@@ -448,8 +466,8 @@ fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta)
                sid_append_rid(&member_sid, delta->rids[i]);
 
                if (!pdb_getsampwsid(member, &member_sid)) {
-                       DEBUG(1, ("Found bogus group member: %d\n",
-                                 delta->rids[i]));
+                       DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
+                                 delta->rids[i], sid_string_static(&member_sid), grp->gr_name));
                        pdb_free_sam(&member);
                        continue;
                }
@@ -530,7 +548,7 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
        DOM_SID alias_sid;
        fstring sid_string;
        GROUP_MAP map;
-       int insert_flag = TDB_INSERT;
+       BOOL insert = True;
 
        unistr2_to_ascii(name, &delta->uni_als_name, sizeof(name)-1);
        unistr2_to_ascii(comment, &delta->uni_als_desc, sizeof(comment)-1);
@@ -540,9 +558,9 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
        sid_append_rid(&alias_sid, rid);
        sid_to_string(sid_string, &alias_sid);
 
-       if (get_group_map_from_sid(alias_sid, &map, False)) {
+       if (pdb_getgrsid(&map, alias_sid, False)) {
                grp = getgrgid(map.gid);
-               insert_flag = 0; /* Don't TDB_INSERT, mapping exists */
+               insert = False;
        }
 
        if (grp == NULL) {
@@ -573,7 +591,10 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
        map.priv_set.count = 0;
        map.priv_set.set = NULL;
 
-       add_mapping_entry(&map, insert_flag);
+       if (insert)
+               pdb_add_group_mapping_entry(&map);
+       else
+               pdb_update_group_mapping_entry(&map);
 
        return NT_STATUS_OK;
 }
@@ -620,7 +641,7 @@ static void
 fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
               DOM_SID dom_sid)
 {
-       unsigned last_rid = -1;
+       unsigned sync_context = 0;
         NTSTATUS result;
        int i;
         TALLOC_CTX *mem_ctx;
@@ -628,7 +649,7 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
         SAM_DELTA_CTR *deltas;
         uint32 num_deltas;
 
-       if (!(mem_ctx = talloc_init())) {
+       if (!(mem_ctx = talloc_init("fetch_database"))) {
                return;
        }
 
@@ -636,17 +657,16 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
 
        do {
                result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds,
-                                              db_type, last_rid+1,
+                                              db_type, sync_context,
                                               &num_deltas,
                                               &hdr_deltas, &deltas);
                clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred),
                                     ret_creds);
-               last_rid = 0;
                 for (i = 0; i < num_deltas; i++) {
                        fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid);
-                       last_rid = hdr_deltas[i].target_rid;
                 }
-       } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
+               sync_context += 1;
+       } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 
        talloc_destroy(mem_ctx);
 }
@@ -676,7 +696,7 @@ int rpc_vampire(int argc, const char **argv)
 
        if (!secrets_fetch_trust_account_password(lp_workgroup(),
                                                  trust_password, NULL)) {
-               d_printf("Could not retrieve domain trust secret");
+               d_printf("Could not retrieve domain trust secret\n");
                goto fail;
        }