Fix coverity CID#115. Resource leak in error path.
[metze/samba/wip.git] / source3 / libnet / libnet_samsync_ldif.c
index c89fedc2a3582f77d2aa6ea25714e1b02bf133e6..4286331893575959c8e5d66586d39f855bca4115 100644 (file)
 #include "includes.h"
 #include "libnet/libnet_samsync.h"
 
+#ifdef HAVE_LDAP
+
 /* uid's and gid's for writing deltas to ldif */
 static uint32 ldif_gid = 999;
 static uint32 ldif_uid = 999;
 
+/* global counters */
+static uint32_t g_index = 0;
+static uint32_t a_index = 0;
+
 /* Structure for mapping accounts to groups */
 /* Array element is the group rid */
 typedef struct _groupmap {
@@ -178,8 +184,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        fprintf(add_fd, "# %s, %s\n", lp_workgroup(), suffix);
        fprintf(add_fd, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
                suffix);
-       fprintf(add_fd, "objectClass: sambaDomain\n");
-       fprintf(add_fd, "objectClass: sambaUnixIdPool\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_DOMINFO);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_IDPOOL);
        fprintf(add_fd, "sambaDomainName: %s\n", lp_workgroup());
        fprintf(add_fd, "sambaSID: %s\n", sid);
        fprintf(add_fd, "uidNumber: %d\n", ++ldif_uid);
@@ -192,8 +198,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: Domain Admins\n");
        fprintf(add_fd, "memberUid: Administrator\n");
        fprintf(add_fd, "description: Netbios Domain Administrators\n");
@@ -209,8 +215,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: Domain Users\n");
        fprintf(add_fd, "description: Netbios Domain Users\n");
        fprintf(add_fd, "gidNumber: 513\n");
@@ -225,8 +231,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: Domain Guests\n");
        fprintf(add_fd, "description: Netbios Domain Guests\n");
        fprintf(add_fd, "gidNumber: 514\n");
@@ -241,8 +247,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Domain Computers,ou=%s,%s\n",
                group_attr, suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 515\n");
        fprintf(add_fd, "cn: Domain Computers\n");
        fprintf(add_fd, "description: Netbios Domain Computers accounts\n");
@@ -257,8 +263,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Administrators,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 544\n");
        fprintf(add_fd, "cn: Administrators\n");
        fprintf(add_fd, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
@@ -272,8 +278,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Print Operators,ou=%s,%s\n",
                group_attr, suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 550\n");
        fprintf(add_fd, "cn: Print Operators\n");
        fprintf(add_fd, "description: Netbios Domain Print Operators\n");
@@ -288,8 +294,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
                suffix);
        fprintf(add_fd, "dn: cn=Backup Operators,ou=%s,%s\n",
                group_attr, suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 551\n");
        fprintf(add_fd, "cn: Backup Operators\n");
        fprintf(add_fd, "description: Netbios Domain Members can bypass file security to back up files\n");
@@ -303,8 +309,8 @@ static NTSTATUS populate_ldap_for_ldif(const char *sid,
        fprintf(add_fd, "# Replicators, %s, %s\n", group_attr, suffix);
        fprintf(add_fd, "dn: cn=Replicators,ou=%s,%s\n", group_attr,
                suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "gidNumber: 552\n");
        fprintf(add_fd, "cn: Replicators\n");
        fprintf(add_fd, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
@@ -544,8 +550,8 @@ static NTSTATUS fetch_group_info_to_ldif(TALLOC_CTX *mem_ctx,
                suffix);
        fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", groupname, group_attr,
                     suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf_attr(add_fd, "cn", "%s", groupname);
        fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
        fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
@@ -574,14 +580,15 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
        fstring username, logonscript, homedrive, homepath = "", homedir = "";
        fstring hex_nt_passwd, hex_lm_passwd;
        fstring description, profilepath, fullname, sambaSID;
-       uchar lm_passwd[16], nt_passwd[16];
        char *flags, *user_rdn;
        const char *ou;
        const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
-       static uchar zero_buf[16];
+       uchar zero_buf[16];
        uint32 rid = 0, group_rid = 0, gidNumber = 0;
        time_t unix_time;
-       int i;
+       int i, ret;
+
+       memset(zero_buf, '\0', sizeof(zero_buf));
 
        /* Get the username */
        fstrcpy(username, r->account_name.string);
@@ -628,14 +635,12 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
 
        /* Get lm and nt password data */
        if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
-               sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0);
-               pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags);
+               pdb_sethexpwd(hex_lm_passwd, r->lmpassword.hash, r->acct_flags);
        } else {
                pdb_sethexpwd(hex_lm_passwd, NULL, 0);
        }
        if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
-               sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0);
-               pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags);
+               pdb_sethexpwd(hex_nt_passwd, r->ntpassword.hash, r->acct_flags);
        } else {
                pdb_sethexpwd(hex_nt_passwd, NULL, 0);
        }
@@ -655,7 +660,10 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
                return NT_STATUS_UNSUCCESSFUL;
        }
        gidNumber = groupmap[i].gidNumber;
-       snprintf(sambaSID, sizeof(sambaSID), groupmap[i].sambaSID);
+       ret = snprintf(sambaSID, sizeof(sambaSID), "%s", groupmap[i].sambaSID);
+       if (ret < 0 || ret == sizeof(sambaSID)) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
        /* Set up sambaAcctFlags */
        flags = pdb_encode_acct_ctrl(r->acct_flags,
@@ -670,9 +678,9 @@ static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
        SAFE_FREE(user_rdn);
        fprintf(add_fd, "ObjectClass: top\n");
        fprintf(add_fd, "objectClass: inetOrgPerson\n");
-       fprintf(add_fd, "objectClass: posixAccount\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXACCOUNT);
        fprintf(add_fd, "objectClass: shadowAccount\n");
-       fprintf(add_fd, "objectClass: sambaSamAccount\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_SAMBASAMACCOUNT);
        fprintf_attr(add_fd, "cn", "%s", username);
        fprintf_attr(add_fd, "sn", "%s", username);
        fprintf_attr(add_fd, "uid", "%s", username);
@@ -768,15 +776,18 @@ static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
        g_rid = r->rid;
        groupmap->gidNumber = ldif_gid;
        groupmap->sambaSID = talloc_asprintf(mem_ctx, "%s-%d", sid, g_rid);
-       NT_STATUS_HAVE_NO_MEMORY(groupmap->sambaSID);
+       if (groupmap->sambaSID == NULL) {
+               SAFE_FREE(group_attr);
+               return NT_STATUS_NO_MEMORY;
+       }
 
        /* Write the data to the temporary add ldif file */
        fprintf(add_fd, "# %s, %s, %s\n", aliasname, group_attr,
                suffix);
        fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", aliasname, group_attr,
                     suffix);
-       fprintf(add_fd, "objectClass: posixGroup\n");
-       fprintf(add_fd, "objectClass: sambaGroupMapping\n");
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_POSIXGROUP);
+       fprintf(add_fd, "objectClass: %s\n", LDAP_OBJ_GROUPMAP);
        fprintf(add_fd, "cn: %s\n", aliasname);
        fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
        fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
@@ -1045,8 +1056,8 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
                                     enum netr_SamDatabaseID database_id,
                                     struct netr_DELTA_ENUM *r,
                                     struct samsync_context *ctx,
-                                    uint32_t *a_index,
-                                    uint32_t *g_index)
+                                    uint32_t *a_index_p,
+                                    uint32_t *g_index_p)
 {
        union netr_DELTA_UNION u = r->delta_union;
        union netr_DELTA_ID_UNION id = r->delta_id_union;
@@ -1060,34 +1071,34 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
                case NETR_DELTA_GROUP:
                        fetch_group_info_to_ldif(mem_ctx,
                                                 u.group,
-                                                &l->groupmap[*g_index],
+                                                &l->groupmap[*g_index_p],
                                                 l->add_file,
                                                 ctx->domain_sid_str,
                                                 l->suffix);
-                       (*g_index)++;
+                       (*g_index_p)++;
                        break;
 
                case NETR_DELTA_USER:
                        fetch_account_info_to_ldif(mem_ctx,
                                                   u.user,
                                                   l->groupmap,
-                                                  &l->accountmap[*a_index],
+                                                  &l->accountmap[*a_index_p],
                                                   l->add_file,
                                                   ctx->domain_sid_str,
                                                   l->suffix,
                                                   l->num_alloced);
-                       (*a_index)++;
+                       (*a_index_p)++;
                        break;
 
                case NETR_DELTA_ALIAS:
                        fetch_alias_info_to_ldif(mem_ctx,
                                                 u.alias,
-                                                &l->groupmap[*g_index],
+                                                &l->groupmap[*g_index_p],
                                                 l->add_file,
                                                 ctx->domain_sid_str,
                                                 l->suffix,
                                                 database_id);
-                       (*g_index)++;
+                       (*g_index_p)++;
                        break;
 
                case NETR_DELTA_GROUP_MEMBER:
@@ -1155,15 +1166,12 @@ static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
-                               enum netr_SamDatabaseID database_id,
-                               struct netr_DELTA_ENUM_ARRAY *r,
-                               bool last_query,
-                               struct samsync_context *ctx)
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+                         struct samsync_context *ctx,
+                         enum netr_SamDatabaseID database_id,
+                         uint64_t *sequence_num)
 {
        NTSTATUS status;
-       int i;
-       uint32_t g_index = 0, a_index = 0;
        struct samsync_ldif_context *ldif_ctx =
                (struct samsync_ldif_context *)ctx->private_data;
 
@@ -1173,11 +1181,28 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
                                   ctx->domain_sid_str,
                                   &ldif_ctx);
        if (!NT_STATUS_IS_OK(status)) {
-               goto failed;
+               return status;
        }
 
        ctx->private_data = ldif_ctx;
 
+       return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+                                      enum netr_SamDatabaseID database_id,
+                                      struct netr_DELTA_ENUM_ARRAY *r,
+                                      uint64_t *sequence_num,
+                                      struct samsync_context *ctx)
+{
+       NTSTATUS status;
+       int i;
+       struct samsync_ldif_context *ldif_ctx =
+               (struct samsync_ldif_context *)ctx->private_data;
+
        status = ldif_realloc_maps(mem_ctx, ldif_ctx, r->num_deltas);
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
@@ -1192,18 +1217,6 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
                }
        }
 
-       /* This was the last query */
-       if (last_query) {
-               ldif_write_output(database_id, ldif_ctx);
-               if (ldif_ctx->ldif_file != stdout) {
-                       ctx->result_message = talloc_asprintf(mem_ctx,
-                               "Vampired %d accounts and %d groups to %s",
-                               a_index, g_index, ctx->output_filename);
-               }
-               ldif_free_context(ldif_ctx);
-               ctx->private_data = NULL;
-       }
-
        return NT_STATUS_OK;
 
  failed:
@@ -1212,3 +1225,63 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
 
        return status;
 }
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+                          struct samsync_context *ctx,
+                          enum netr_SamDatabaseID database_id,
+                          uint64_t sequence_num)
+{
+       struct samsync_ldif_context *ldif_ctx =
+               (struct samsync_ldif_context *)ctx->private_data;
+
+       /* This was the last query */
+       ldif_write_output(database_id, ldif_ctx);
+       if (ldif_ctx->ldif_file != stdout) {
+               ctx->result_message = talloc_asprintf(ctx,
+                       "Vampired %d accounts and %d groups to %s",
+                       a_index, g_index, ctx->output_filename);
+       }
+
+       ldif_free_context(ldif_ctx);
+       ctx->private_data = NULL;
+
+       return NT_STATUS_OK;
+}
+
+#else /* HAVE_LDAP */
+
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+                         struct samsync_context *ctx,
+                         enum netr_SamDatabaseID database_id,
+                         uint64_t *sequence_num)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+                                      enum netr_SamDatabaseID database_id,
+                                      struct netr_DELTA_ENUM_ARRAY *r,
+                                      uint64_t *sequence_num,
+                                      struct samsync_context *ctx)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+                          struct samsync_context *ctx,
+                          enum netr_SamDatabaseID database_id,
+                          uint64_t sequence_num)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+#endif
+
+const struct samsync_ops libnet_samsync_ldif_ops = {
+       .startup                = init_ldif,
+       .process_objects        = fetch_sam_entries_ldif,
+       .finish                 = close_ldif,
+};