r14681: Get rid of hardcoded /tmp/add.ldif and /tmp/mod.ldif files. Is there a
[tprouty/samba.git] / source3 / utils / net_rpc_samsync.c
index fa196af5eda0589dccfa1001ac6dc542cfec4b83..ae8d2cdc081f282413f9ef5122fec46ef8c15c6c 100644 (file)
@@ -305,6 +305,10 @@ NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid,
                    (!old_string && new_string) ||\
                (old_string && new_string && (strcmp(old_string, new_string) != 0))
 
+#define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
+                   (!(s1) && (s2)) ||\
+               ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
+
 static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *delta)
 {
        const char *old_string, *new_string;
@@ -389,13 +393,15 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d
 
        if (delta->hdr_parameters.buffer) {
                DATA_BLOB mung;
+               char *newstr;
                old_string = pdb_get_munged_dial(account);
                mung.length = delta->hdr_parameters.uni_str_len;
                mung.data = (uint8 *) delta->uni_parameters.buffer;
-               new_string = (mung.length == 0) ? NULL : base64_encode_data_blob(mung);
+               newstr = (mung.length == 0) ? NULL : base64_encode_data_blob(mung);
 
-               if (STRING_CHANGED)
-                       pdb_set_munged_dial(account, new_string, PDB_CHANGED);
+               if (STRING_CHANGED_NC(old_string, newstr))
+                       pdb_set_munged_dial(account, newstr, PDB_CHANGED);
+               SAFE_FREE(newstr);
        }
 
        /* User and group sid */
@@ -1070,11 +1076,15 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch
        if (machine_suffix && *machine_suffix && 
            strcmp(machine_suffix, user_suffix) &&
            strcmp(machine_suffix, suffix)) {
-               fprintf(add_fd, "# %s\n", lp_ldap_machine_suffix());
-               fprintf(add_fd, "dn: %s\n", lp_ldap_machine_suffix());
+               char *machine_ou = NULL;
+               fprintf(add_fd, "# %s\n", machine_suffix);
+               fprintf(add_fd, "dn: %s\n", machine_suffix);
                fprintf(add_fd, "objectClass: organizationalUnit\n");
-               fprintf(add_fd, "ou: %s\n", 
-                       sstring_sub(lp_ldap_machine_suffix(), '=', ','));
+               /* this isn't totally correct as it assumes that
+                  there _must_ be an ou. just fixing memleak now. jmcd */
+               machine_ou = sstring_sub(lp_ldap_machine_suffix(), '=', ',');
+               fprintf(add_fd, "ou: %s\n", machine_ou);
+               SAFE_FREE(machine_ou);
                fprintf(add_fd, "\n");
                fflush(add_fd);
        }
@@ -1085,11 +1095,13 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch
        if (idmap_suffix && *idmap_suffix &&
            strcmp(idmap_suffix, user_suffix) &&
            strcmp(idmap_suffix, suffix)) {
+               char *s;
                fprintf(add_fd, "# %s\n", idmap_suffix);
                fprintf(add_fd, "dn: %s\n", idmap_suffix);
                fprintf(add_fd, "ObjectClass: organizationalUnit\n");
-               fprintf(add_fd, "ou: %s\n", 
-                       sstring_sub(lp_ldap_idmap_suffix(), '=', ','));
+               s = sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
+               fprintf(add_fd, "ou: %s\n", s);
+               SAFE_FREE(s);
                fprintf(add_fd, "\n");
                fflush(add_fd);
        }
@@ -1150,7 +1162,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch
        fprintf(add_fd, "gidNumber: 514\n");
        fprintf(add_fd, "uid: nobody\n");
        fprintf(add_fd, "uidNumber: 999\n");
-       fprintf(add_fd, "homeDirectory: /dev/null\n");
+       fprintf(add_fd, "homeDirectory: /nobodyshomedir\n");
        fprintf(add_fd, "sambaPwdLastSet: 0\n");
        fprintf(add_fd, "sambaLogonTime: 0\n");
        fprintf(add_fd, "sambaLogoffTime: 2147483647\n");
@@ -1297,7 +1309,9 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch
        fflush(add_fd);
 
        /* Deallocate memory, and return */
-       if (suffix_attr != NULL) SAFE_FREE(suffix_attr);
+       SAFE_FREE(suffix_attr);
+       SAFE_FREE(user_attr);
+       SAFE_FREE(group_attr);
        return NT_STATUS_OK;
 }
 
@@ -1370,6 +1384,7 @@ static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap,
                     group_attr, suffix);
        accountmap[7].rid = 551;
        pstr_sprintf(accountmap[7].cn, "%s", "Replicators");
+       SAFE_FREE(group_attr);
        return NT_STATUS_OK;
 }
 
@@ -1397,6 +1412,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma
            strcmp(groupname, "Print Operators") == 0 ||
            strcmp(groupname, "Backup Operators") == 0 ||
            strcmp(groupname, "Replicators") == 0) {
+               SAFE_FREE(group_attr);
                return NT_STATUS_OK;
        } else {
                /* Increment the gid for the new group */
@@ -1426,6 +1442,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma
        fprintf(add_fd, "\n");
        fflush(add_fd);
 
+       SAFE_FREE(group_attr);
        /* Return */
        return NT_STATUS_OK;
 }
@@ -1438,7 +1455,7 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *group
        fstring hex_nt_passwd, hex_lm_passwd;
        fstring description, fullname, sambaSID;
        uchar lm_passwd[16], nt_passwd[16];
-       char *flags;
+       char *flags, *user_rdn;
        const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        static uchar zero_buf[16];
        uint32 rid = 0, group_rid = 0, gidNumber = 0;
@@ -1464,7 +1481,7 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *group
                if (!*homedir) {
                        pstr_sprintf(homedir, "/home/%s", username);
                } else {
-                       pstr_sprintf(homedir, "dev/null");
+                       pstr_sprintf(homedir, "/nobodyshomedir");
                }
        }       
 
@@ -1534,10 +1551,11 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *group
                                     NEW_PW_FORMAT_SPACE_PADDED_LEN);
 
        /* Add the user to the temporary add ldif file */
-       fprintf(add_fd, "# %s, %s, %s\n", username, 
-               sstring_sub(lp_ldap_user_suffix(), '=', ','), suffix);
-       fprintf(add_fd, "dn: uid=%s,ou=%s,%s\n", username, 
-               sstring_sub(lp_ldap_user_suffix(), '=', ','), suffix);
+       /* this isn't quite right...we can't assume there's just OU=. jmcd */
+       user_rdn = sstring_sub(lp_ldap_user_suffix(), '=', ',');
+       fprintf(add_fd, "# %s, %s, %s\n", username, user_rdn, suffix);
+       fprintf(add_fd, "dn: uid=%s,ou=%s,%s\n", username, user_rdn, suffix);
+       SAFE_FREE(user_rdn);
        fprintf(add_fd, "ObjectClass: top\n");
        fprintf(add_fd, "objectClass: inetOrgPerson\n");
        fprintf(add_fd, "objectClass: posixAccount\n");
@@ -1619,6 +1637,7 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma
            strcmp(aliasname, "Print Operators") == 0 ||
            strcmp(aliasname, "Backup Operators") == 0 ||
            strcmp(aliasname, "Replicator") == 0) {
+               SAFE_FREE(group_attr);
                return NT_STATUS_OK;
        } else {
                /* Increment the gid for the new group */
@@ -1646,6 +1665,7 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma
        fprintf(add_fd, "\n");
        fflush(add_fd);
 
+       SAFE_FREE(group_attr);
        /* Return */
        return NT_STATUS_OK;
 }
@@ -1699,17 +1719,18 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
 {
        char *suffix;
        const char *builtin_sid = "S-1-5-32";
-       char *ldif_file;
+       char *ldif_file, *add_ldif, *mod_ldif;
+       const char *add_template = "/tmp/add.ldif.XXXXXX";
+       const char *mod_template = "/tmp/mod.ldif.XXXXXX";
        fstring sid, domainname;
        uint32 sync_context = 0;
-       NTSTATUS result;
+       NTSTATUS ret = NT_STATUS_OK, result;
        int k;
        TALLOC_CTX *mem_ctx;
        SAM_DELTA_HDR *hdr_deltas;
        SAM_DELTA_CTR *deltas;
        uint32 num_deltas;
-       const char *add_ldif = "/tmp/add.ldif", *mod_ldif = "/tmp/mod.ldif";
-       FILE *add_fd, *mod_fd, *ldif_fd;
+       FILE *add_fd = NULL, *mod_fd = NULL, *ldif_fd = NULL;
        char sys_cmd[1024];
        int num_alloced = 0, g_index = 0, a_index = 0, sys_cmd_result;
 
@@ -1731,22 +1752,31 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
        else
                ldif_file = talloc_strdup(mem_ctx, "/tmp/tmp.ldif");
        
-       if (ldif_file == NULL)
-               return NT_STATUS_NO_MEMORY;
+       add_ldif = talloc_strdup(mem_ctx, add_template);
+       mod_ldif = talloc_strdup(mem_ctx, mod_template);
+       if (!ldif_file || !add_ldif || !mod_ldif) {
+               ret = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
 
        /* Open the add and mod ldif files */
-       add_fd = fopen(add_ldif, "a");
-       mod_fd = fopen(mod_ldif, "a");
-       if (add_fd == NULL || mod_fd == NULL) {
+       if (!(add_fd = fdopen(smb_mkstemp(add_ldif),"w"))) {
                DEBUG(1, ("Could not open %s\n", add_ldif));
-               return NT_STATUS_UNSUCCESSFUL;
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+       if (!(mod_fd = fdopen(smb_mkstemp(mod_ldif),"w"))) {
+               DEBUG(1, ("Could not open %s\n", mod_ldif));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
        } 
 
        /* Open the user's ldif file */
        ldif_fd = fopen(ldif_file, "a");
        if (ldif_fd == NULL) {
                DEBUG(1, ("Could not open %s\n", ldif_file));
-               return NT_STATUS_UNSUCCESSFUL;
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
        }
 
        /* Get the sid */
@@ -1771,7 +1801,8 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
                accountmap = SMB_MALLOC_ARRAY(ACCOUNTMAP, 8);
                if (groupmap == NULL || accountmap == NULL) {
                        DEBUG(1,("GROUPMAP malloc failed\n"));
-                       return NT_STATUS_NO_MEMORY;
+                       ret = NT_STATUS_NO_MEMORY;
+                       goto done;
                }
 
                /* Initialize the arrays */
@@ -1813,7 +1844,8 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
                                               &deltas);
                if (!NT_STATUS_IS_OK(result) &&
                    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
-                       return NT_STATUS_OK;
+                       ret = NT_STATUS_OK;
+                       goto done; /* is this correct? jmcd */
                }
 
                /* Re-allocate memory for groupmap and accountmap arrays */
@@ -1823,9 +1855,8 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
                                        num_deltas+num_alloced);
                if (groupmap == NULL || accountmap == NULL) {
                        DEBUG(1,("GROUPMAP malloc failed\n"));
-                       SAFE_FREE(groupmap);
-                       SAFE_FREE(accountmap);
-                       return NT_STATUS_NO_MEMORY;
+                       ret = NT_STATUS_NO_MEMORY;
+                       goto done;
                }
 
                /* Initialize the new records */
@@ -1917,7 +1948,9 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
 
        /* Close the ldif files */
        fclose(add_fd);
+       add_fd = NULL;
        fclose(mod_fd);
+       mod_fd = NULL;
 
        /* Write ldif data to the user's file */
        if (db_type == SAM_DATABASE_DOMAIN) {
@@ -1938,7 +1971,8 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
        if (sys_cmd_result) {
                d_fprintf(stderr, "%s failed.  Error was (%s)\n",
                        sys_cmd, strerror(errno));
-               return NT_STATUS_UNSUCCESSFUL;
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
        }
        if (db_type == SAM_DATABASE_DOMAIN) {
                fprintf(ldif_fd,
@@ -1958,20 +1992,28 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
        if (sys_cmd_result) {
                d_fprintf(stderr, "%s failed.  Error was (%s)\n",
                        sys_cmd, strerror(errno));
-               return NT_STATUS_UNSUCCESSFUL;
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
        }
 
-       /* Delete the temporary ldif files */
-       pstr_sprintf(sys_cmd, "rm -f %s %s", add_ldif, mod_ldif);
-       sys_cmd_result = system(sys_cmd);
-       if (sys_cmd_result) {
-               d_fprintf(stderr, "%s failed.  Error was (%s)\n",
-                       sys_cmd, strerror(errno));
-               return NT_STATUS_UNSUCCESSFUL;
+  done:
+       /* Close and delete the ldif files */
+       if (add_fd)
+               fclose(add_fd);
+       if (strcmp(add_ldif, add_template) && (unlink(add_ldif))) {
+               DEBUG(1,("unlink(%s) failed, error was (%s)\n",
+                        add_ldif, strerror(errno)));
        }
 
-       /* Close the ldif file */
-       fclose(ldif_fd);
+       if (mod_fd)
+               fclose(mod_fd);
+       if (strcmp(mod_ldif, mod_template) && (unlink(mod_ldif))) {
+               DEBUG(1,("unlink(%s) failed, error was (%s)\n",
+                        mod_ldif, strerror(errno)));
+       }
+       
+       if (ldif_fd)
+               fclose(ldif_fd);
 
        /* Deallocate memory for the mapping arrays */
        SAFE_FREE(groupmap);
@@ -1979,7 +2021,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
 
        /* Return */
        talloc_destroy(mem_ctx);
-       return NT_STATUS_OK;
+       return ret;
 }
 
 /**