LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules/tests - test_audit_log.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 1460 1460 100.0 %
Date: 2024-05-31 13:13:24 Functions: 25 25 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unit tests for the dsdb audit logging code code in audit_log.c
       3             : 
       4             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include <stdarg.h>
      21             : #include <stddef.h>
      22             : #include <setjmp.h>
      23             : #include <unistd.h>
      24             : #include <cmocka.h>
      25             : 
      26             : int ldb_audit_log_module_init(const char *version);
      27             : #include "../audit_log.c"
      28             : 
      29             : #include "lib/ldb/include/ldb_private.h"
      30             : #include <regex.h>
      31             : #include <float.h>
      32             : 
      33             : /*
      34             :  * Test helper to check ISO 8601 timestamps for validity
      35             :  */
      36           9 : static void check_timestamp(time_t before, const char* timestamp)
      37             : {
      38           9 :         int rc;
      39           9 :         int usec, tz;
      40           9 :         char c[2];
      41           9 :         struct tm tm;
      42           9 :         time_t after;
      43           9 :         time_t actual;
      44           9 :         struct timeval tv;
      45             : 
      46             : 
      47           9 :         rc = gettimeofday(&tv, NULL);
      48           9 :         assert_return_code(rc, errno);
      49           9 :         after = tv.tv_sec;
      50             : 
      51             :         /*
      52             :          * Convert the ISO 8601 timestamp into a time_t
      53             :          * Note for convenience we ignore the value of the microsecond
      54             :          * part of the time stamp.
      55             :          */
      56           9 :         rc = sscanf(
      57             :                 timestamp,
      58             :                 "%4d-%2d-%2dT%2d:%2d:%2d.%6d%1c%4d",
      59             :                 &tm.tm_year,
      60             :                 &tm.tm_mon,
      61             :                 &tm.tm_mday,
      62             :                 &tm.tm_hour,
      63             :                 &tm.tm_min,
      64             :                 &tm.tm_sec,
      65             :                 &usec,
      66             :                 c,
      67             :                 &tz);
      68           9 :         assert_int_equal(9, rc);
      69           9 :         tm.tm_year = tm.tm_year - 1900;
      70           9 :         tm.tm_mon = tm.tm_mon - 1;
      71           9 :         tm.tm_isdst = -1;
      72           9 :         actual = mktime(&tm);
      73             : 
      74             :         /*
      75             :          * The timestamp should be before <= actual <= after
      76             :          */
      77           9 :         assert_in_range(actual, before, after);
      78           9 : }
      79             : 
      80           1 : static void test_has_password_changed(void **state)
      81             : {
      82           1 :         struct ldb_context *ldb = NULL;
      83           1 :         struct ldb_message *msg = NULL;
      84             : 
      85           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
      86             : 
      87           1 :         ldb = ldb_init(ctx, NULL);
      88             : 
      89             :         /*
      90             :          * Empty message
      91             :          */
      92           1 :         msg = ldb_msg_new(ldb);
      93           1 :         assert_false(has_password_changed(msg));
      94           1 :         TALLOC_FREE(msg);
      95             : 
      96             :         /*
      97             :          * No password attributes
      98             :          */
      99           1 :         msg = ldb_msg_new(ldb);
     100           1 :         ldb_msg_add_string(msg, "attr01", "value01");
     101           1 :         assert_false(has_password_changed(msg));
     102           1 :         TALLOC_FREE(msg);
     103             : 
     104             :         /*
     105             :          * No password attributes >1 entries
     106             :          */
     107           1 :         msg = ldb_msg_new(ldb);
     108           1 :         ldb_msg_add_string(msg, "attr01", "value01");
     109           1 :         ldb_msg_add_string(msg, "attr02", "value03");
     110           1 :         ldb_msg_add_string(msg, "attr03", "value03");
     111           1 :         assert_false(has_password_changed(msg));
     112           1 :         TALLOC_FREE(msg);
     113             : 
     114             :         /*
     115             :          *  userPassword set
     116             :          */
     117           1 :         msg = ldb_msg_new(ldb);
     118           1 :         ldb_msg_add_string(msg, "userPassword", "value01");
     119           1 :         assert_true(has_password_changed(msg));
     120           1 :         TALLOC_FREE(msg);
     121             : 
     122             :         /*
     123             :          *  clearTextPassword set
     124             :          */
     125           1 :         msg = ldb_msg_new(ldb);
     126           1 :         ldb_msg_add_string(msg, "clearTextPassword", "value01");
     127           1 :         assert_true(has_password_changed(msg));
     128           1 :         TALLOC_FREE(msg);
     129             : 
     130             :         /*
     131             :          *  unicodePwd set
     132             :          */
     133           1 :         msg = ldb_msg_new(ldb);
     134           1 :         ldb_msg_add_string(msg, "unicodePwd", "value01");
     135           1 :         assert_true(has_password_changed(msg));
     136           1 :         TALLOC_FREE(msg);
     137             : 
     138             :         /*
     139             :          *  dBCSPwd set
     140             :          */
     141           1 :         msg = ldb_msg_new(ldb);
     142           1 :         ldb_msg_add_string(msg, "dBCSPwd", "value01");
     143           1 :         assert_true(has_password_changed(msg));
     144           1 :         TALLOC_FREE(msg);
     145             : 
     146             :         /*
     147             :          *  All attributes set
     148             :          */
     149           1 :         msg = ldb_msg_new(ldb);
     150           1 :         ldb_msg_add_string(msg, "userPassword", "value01");
     151           1 :         ldb_msg_add_string(msg, "clearTextPassword", "value02");
     152           1 :         ldb_msg_add_string(msg, "unicodePwd", "value03");
     153           1 :         ldb_msg_add_string(msg, "dBCSPwd", "value04");
     154           1 :         assert_true(has_password_changed(msg));
     155           1 :         TALLOC_FREE(msg);
     156             : 
     157             :         /*
     158             :          *  first attribute is a password attribute
     159             :          */
     160           1 :         msg = ldb_msg_new(ldb);
     161           1 :         ldb_msg_add_string(msg, "userPassword", "value01");
     162           1 :         ldb_msg_add_string(msg, "attr02", "value02");
     163           1 :         ldb_msg_add_string(msg, "attr03", "value03");
     164           1 :         ldb_msg_add_string(msg, "attr04", "value04");
     165           1 :         assert_true(has_password_changed(msg));
     166           1 :         TALLOC_FREE(msg);
     167             : 
     168             :         /*
     169             :          *  last attribute is a password attribute
     170             :          */
     171           1 :         msg = ldb_msg_new(ldb);
     172           1 :         ldb_msg_add_string(msg, "attr01", "value01");
     173           1 :         ldb_msg_add_string(msg, "attr02", "value02");
     174           1 :         ldb_msg_add_string(msg, "attr03", "value03");
     175           1 :         ldb_msg_add_string(msg, "clearTextPassword", "value04");
     176           1 :         assert_true(has_password_changed(msg));
     177           1 :         TALLOC_FREE(msg);
     178             : 
     179             :         /*
     180             :          *  middle attribute is a password attribute
     181             :          */
     182           1 :         msg = ldb_msg_new(ldb);
     183           1 :         ldb_msg_add_string(msg, "attr01", "value01");
     184           1 :         ldb_msg_add_string(msg, "attr02", "value02");
     185           1 :         ldb_msg_add_string(msg, "unicodePwd", "pwd");
     186           1 :         ldb_msg_add_string(msg, "attr03", "value03");
     187           1 :         ldb_msg_add_string(msg, "attr04", "value04");
     188           1 :         assert_true(has_password_changed(msg));
     189           1 :         TALLOC_FREE(msg);
     190             : 
     191           1 :         TALLOC_FREE(ctx);
     192           1 : }
     193             : 
     194           1 : static void test_get_password_action(void **state)
     195             : {
     196           1 :         struct ldb_context *ldb = NULL;
     197           1 :         struct ldb_request *req = NULL;
     198           1 :         struct ldb_reply *reply = NULL;
     199           1 :         struct dsdb_control_password_acl_validation *pav = NULL;
     200           1 :         int ret;
     201             : 
     202           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     203           1 :         ldb = ldb_init(ctx, NULL);
     204             : 
     205             :         /*
     206             :          * Add request, will always be a reset
     207             :          */
     208           1 :         ldb_build_add_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
     209           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     210           1 :         assert_string_equal("Reset", get_password_action(req, reply));
     211           1 :         TALLOC_FREE(req);
     212           1 :         TALLOC_FREE(reply);
     213             : 
     214             :         /*
     215             :          * No password control acl, expect "Reset"
     216             :          */
     217           1 :         ldb_build_mod_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
     218           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     219           1 :         assert_string_equal("Reset", get_password_action(req, reply));
     220           1 :         TALLOC_FREE(req);
     221           1 :         TALLOC_FREE(reply);
     222             : 
     223             :         /*
     224             :          * dsdb_control_password_acl_validation reset = false, expect "Change"
     225             :          */
     226           1 :         ret = ldb_build_mod_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
     227           1 :         assert_int_equal(ret, LDB_SUCCESS);
     228           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     229           1 :         pav = talloc_zero(req, struct dsdb_control_password_acl_validation);
     230             : 
     231           1 :         ldb_reply_add_control(
     232             :                 reply,
     233             :                 DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID,
     234             :                 false,
     235             :                 pav);
     236           1 :         assert_string_equal("Change", get_password_action(req, reply));
     237           1 :         TALLOC_FREE(req);
     238           1 :         TALLOC_FREE(reply);
     239             : 
     240             :         /*
     241             :          * dsdb_control_password_acl_validation reset = true, expect "Reset"
     242             :          */
     243           1 :         ldb_build_mod_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
     244           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     245           1 :         pav = talloc_zero(req, struct dsdb_control_password_acl_validation);
     246           1 :         pav->pwd_reset = true;
     247             : 
     248           1 :         ldb_reply_add_control(
     249             :                 reply,
     250             :                 DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID,
     251             :                 false,
     252             :                 pav);
     253           1 :         assert_string_equal("Reset", get_password_action(req, reply));
     254           1 :         TALLOC_FREE(req);
     255           1 :         TALLOC_FREE(reply);
     256             : 
     257           1 :         TALLOC_FREE(ctx);
     258           1 : }
     259             : 
     260             : /*
     261             :  * Test helper to validate a version object.
     262             :  */
     263           8 : static void check_version(struct json_t *version, int major, int minor)
     264             : {
     265           8 :         struct json_t *v = NULL;
     266             : 
     267           8 :         assert_true(json_is_object(version));
     268           8 :         assert_int_equal(2, json_object_size(version));
     269             : 
     270           8 :         v = json_object_get(version, "major");
     271           8 :         assert_non_null(v);
     272           8 :         assert_int_equal(major, json_integer_value(v));
     273             : 
     274           8 :         v = json_object_get(version, "minor");
     275           8 :         assert_non_null(v);
     276           8 :         assert_int_equal(minor, json_integer_value(v));
     277           8 : }
     278             : 
     279             : /*
     280             :  * minimal unit test of operation_json, that ensures that all the expected
     281             :  * attributes and objects are in the json object.
     282             :  */
     283           1 : static void test_operation_json_empty(void **state)
     284             : {
     285           1 :         struct ldb_context *ldb = NULL;
     286           1 :         struct ldb_module  *module = NULL;
     287           1 :         struct ldb_request *req = NULL;
     288           1 :         struct ldb_reply *reply = NULL;
     289           1 :         struct audit_private *audit_private = NULL;
     290             : 
     291           1 :         struct json_object json;
     292           1 :         json_t *audit = NULL;
     293           1 :         json_t *v = NULL;
     294           1 :         json_t *o = NULL;
     295           1 :         time_t before;
     296           1 :         struct timeval tv;
     297           1 :         int rc;
     298             : 
     299             : 
     300           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     301             : 
     302           1 :         ldb = ldb_init(ctx, NULL);
     303           1 :         audit_private = talloc_zero(ctx, struct audit_private);
     304             : 
     305           1 :         module = talloc_zero(ctx, struct ldb_module);
     306           1 :         module->ldb = ldb;
     307           1 :         ldb_module_set_private(module, audit_private);
     308             : 
     309           1 :         req = talloc_zero(ctx, struct ldb_request);
     310           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     311           1 :         reply->error = LDB_SUCCESS;
     312             : 
     313           1 :         rc = gettimeofday(&tv, NULL);
     314           1 :         assert_return_code(rc, errno);
     315           1 :         before = tv.tv_sec;
     316           1 :         json = operation_json(module, req, reply);
     317           1 :         assert_int_equal(3, json_object_size(json.root));
     318             : 
     319             : 
     320           1 :         v = json_object_get(json.root, "type");
     321           1 :         assert_non_null(v);
     322           1 :         assert_string_equal("dsdbChange", json_string_value(v));
     323             : 
     324           1 :         v = json_object_get(json.root, "timestamp");
     325           1 :         assert_non_null(v);
     326           1 :         assert_true(json_is_string(v));
     327           1 :         check_timestamp(before, json_string_value(v));
     328             : 
     329           1 :         audit = json_object_get(json.root, "dsdbChange");
     330           1 :         assert_non_null(audit);
     331           1 :         assert_true(json_is_object(audit));
     332           1 :         assert_int_equal(10, json_object_size(audit));
     333             : 
     334           1 :         o = json_object_get(audit, "version");
     335           1 :         assert_non_null(o);
     336           1 :         check_version(o, OPERATION_MAJOR, OPERATION_MINOR);
     337             : 
     338           1 :         v = json_object_get(audit, "statusCode");
     339           1 :         assert_non_null(v);
     340           1 :         assert_true(json_is_integer(v));
     341           1 :         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
     342             : 
     343           1 :         v = json_object_get(audit, "status");
     344           1 :         assert_non_null(v);
     345           1 :         assert_true(json_is_string(v));
     346           1 :         assert_string_equal("Success", json_string_value(v));
     347             : 
     348           1 :         v = json_object_get(audit, "operation");
     349           1 :         assert_non_null(v);
     350           1 :         assert_true(json_is_string(v));
     351             :         /*
     352             :          * Search operation constant is zero
     353             :          */
     354           1 :         assert_string_equal("Search", json_string_value(v));
     355             : 
     356           1 :         v = json_object_get(audit, "remoteAddress");
     357           1 :         assert_non_null(v);
     358           1 :         assert_true(json_is_null(v));
     359             : 
     360           1 :         v = json_object_get(audit, "userSid");
     361           1 :         assert_non_null(v);
     362           1 :         assert_true(json_is_null(v));
     363             : 
     364           1 :         v = json_object_get(audit, "performedAsSystem");
     365           1 :         assert_non_null(v);
     366           1 :         assert_true(json_is_boolean(v));
     367           1 :         assert_true(json_is_false(v));
     368             : 
     369             : 
     370           1 :         v = json_object_get(audit, "dn");
     371           1 :         assert_non_null(v);
     372           1 :         assert_true(json_is_null(v));
     373             : 
     374           1 :         v = json_object_get(audit, "transactionId");
     375           1 :         assert_non_null(v);
     376           1 :         assert_true(json_is_string(v));
     377           1 :         assert_string_equal(
     378             :                 "00000000-0000-0000-0000-000000000000",
     379             :                 json_string_value(v));
     380             : 
     381           1 :         v = json_object_get(audit, "sessionId");
     382           1 :         assert_non_null(v);
     383           1 :         assert_true(json_is_null(v));
     384             : 
     385           1 :         json_free(&json);
     386           1 :         TALLOC_FREE(ctx);
     387             : 
     388           1 : }
     389             : 
     390             : /*
     391             :  * unit test of operation_json, that ensures that all the expected
     392             :  * attributes and objects are in the json object.
     393             :  */
     394           1 : static void test_operation_json(void **state)
     395             : {
     396           1 :         struct ldb_context *ldb = NULL;
     397           1 :         struct ldb_module  *module = NULL;
     398           1 :         struct ldb_request *req = NULL;
     399           1 :         struct ldb_reply *reply = NULL;
     400           1 :         struct audit_private *audit_private = NULL;
     401             : 
     402           1 :         struct tsocket_address *ts = NULL;
     403             : 
     404           1 :         struct auth_session_info *sess = NULL;
     405           1 :         struct security_token *token = NULL;
     406           1 :         struct dom_sid sid;
     407           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
     408           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     409           1 :         struct GUID session_id;
     410             : 
     411           1 :         struct GUID transaction_id;
     412           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     413             : 
     414           1 :         struct ldb_dn *dn = NULL;
     415           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
     416             : 
     417           1 :         struct ldb_message *msg = NULL;
     418             : 
     419           1 :         struct json_object json;
     420           1 :         json_t *audit = NULL;
     421           1 :         json_t *v = NULL;
     422           1 :         json_t *o = NULL;
     423           1 :         json_t *a = NULL;
     424           1 :         json_t *b = NULL;
     425           1 :         json_t *c = NULL;
     426           1 :         json_t *d = NULL;
     427           1 :         json_t *e = NULL;
     428           1 :         json_t *f = NULL;
     429           1 :         json_t *g = NULL;
     430           1 :         time_t before;
     431           1 :         struct timeval tv;
     432           1 :         int rc;
     433             : 
     434             : 
     435           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     436             : 
     437           1 :         ldb = ldb_init(ctx, NULL);
     438             : 
     439           1 :         audit_private = talloc_zero(ctx, struct audit_private);
     440           1 :         GUID_from_string(TRANSACTION, &transaction_id);
     441           1 :         audit_private->transaction_guid = transaction_id;
     442             : 
     443           1 :         module = talloc_zero(ctx, struct ldb_module);
     444           1 :         module->ldb = ldb;
     445           1 :         ldb_module_set_private(module, audit_private);
     446             : 
     447           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
     448           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
     449             : 
     450           1 :         sess = talloc_zero(ctx, struct auth_session_info);
     451           1 :         token = talloc_zero(ctx, struct security_token);
     452           1 :         string_to_sid(&sid, SID);
     453           1 :         token->num_sids = 1;
     454           1 :         token->sids = &sid;
     455           1 :         sess->security_token = token;
     456           1 :         GUID_from_string(SESSION, &session_id);
     457           1 :         sess->unique_session_token = session_id;
     458           1 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
     459             : 
     460           1 :         msg = talloc_zero(ctx, struct ldb_message);
     461           1 :         dn = ldb_dn_new(ctx, ldb, DN);
     462           1 :         msg->dn = dn;
     463           1 :         ldb_msg_add_string(msg, "attribute", "the-value");
     464             : 
     465           1 :         req = talloc_zero(ctx, struct ldb_request);
     466           1 :         req->operation =  LDB_ADD;
     467           1 :         req->op.add.message = msg;
     468             : 
     469           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     470           1 :         reply->error = LDB_ERR_OPERATIONS_ERROR;
     471             : 
     472           1 :         rc = gettimeofday(&tv, NULL);
     473           1 :         assert_return_code(rc, errno);
     474           1 :         before = tv.tv_sec;
     475           1 :         json = operation_json(module, req, reply);
     476           1 :         assert_int_equal(3, json_object_size(json.root));
     477             : 
     478           1 :         v = json_object_get(json.root, "type");
     479           1 :         assert_non_null(v);
     480           1 :         assert_string_equal("dsdbChange", json_string_value(v));
     481             : 
     482           1 :         v = json_object_get(json.root, "timestamp");
     483           1 :         assert_non_null(v);
     484           1 :         assert_true(json_is_string(v));
     485           1 :         check_timestamp(before, json_string_value(v));
     486             : 
     487           1 :         audit = json_object_get(json.root, "dsdbChange");
     488           1 :         assert_non_null(audit);
     489           1 :         assert_true(json_is_object(audit));
     490           1 :         assert_int_equal(11, json_object_size(audit));
     491             : 
     492           1 :         o = json_object_get(audit, "version");
     493           1 :         assert_non_null(o);
     494           1 :         check_version(o, OPERATION_MAJOR, OPERATION_MINOR);
     495             : 
     496           1 :         v = json_object_get(audit, "statusCode");
     497           1 :         assert_non_null(v);
     498           1 :         assert_true(json_is_integer(v));
     499           1 :         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
     500             : 
     501           1 :         v = json_object_get(audit, "status");
     502           1 :         assert_non_null(v);
     503           1 :         assert_true(json_is_string(v));
     504           1 :         assert_string_equal("Operations error", json_string_value(v));
     505             : 
     506           1 :         v = json_object_get(audit, "operation");
     507           1 :         assert_non_null(v);
     508           1 :         assert_true(json_is_string(v));
     509           1 :         assert_string_equal("Add", json_string_value(v));
     510             : 
     511           1 :         v = json_object_get(audit, "remoteAddress");
     512           1 :         assert_non_null(v);
     513           1 :         assert_true(json_is_string(v));
     514           1 :         assert_string_equal("ipv4:127.0.0.1:0", json_string_value(v));
     515             : 
     516           1 :         v = json_object_get(audit, "userSid");
     517           1 :         assert_non_null(v);
     518           1 :         assert_true(json_is_string(v));
     519           1 :         assert_string_equal(SID, json_string_value(v));
     520             : 
     521           1 :         v = json_object_get(audit, "performedAsSystem");
     522           1 :         assert_non_null(v);
     523           1 :         assert_true(json_is_boolean(v));
     524           1 :         assert_true(json_is_false(v));
     525             : 
     526           1 :         v = json_object_get(audit, "dn");
     527           1 :         assert_non_null(v);
     528           1 :         assert_true(json_is_string(v));
     529           1 :         assert_string_equal(DN, json_string_value(v));
     530             : 
     531           1 :         v = json_object_get(audit, "transactionId");
     532           1 :         assert_non_null(v);
     533           1 :         assert_true(json_is_string(v));
     534           1 :         assert_string_equal(TRANSACTION, json_string_value(v));
     535             : 
     536           1 :         v = json_object_get(audit, "sessionId");
     537           1 :         assert_non_null(v);
     538           1 :         assert_true(json_is_string(v));
     539           1 :         assert_string_equal(SESSION, json_string_value(v));
     540             : 
     541           1 :         o = json_object_get(audit, "attributes");
     542           1 :         assert_non_null(v);
     543           1 :         assert_true(json_is_object(o));
     544           1 :         assert_int_equal(1, json_object_size(o));
     545             : 
     546           1 :         a = json_object_get(o, "attribute");
     547           1 :         assert_non_null(a);
     548           1 :         assert_true(json_is_object(a));
     549             : 
     550           1 :         b = json_object_get(a, "actions");
     551           1 :         assert_non_null(b);
     552           1 :         assert_true(json_is_array(b));
     553           1 :         assert_int_equal(1, json_array_size(b));
     554             : 
     555           1 :         c = json_array_get(b, 0);
     556           1 :         assert_non_null(c);
     557           1 :         assert_true(json_is_object(c));
     558             : 
     559           1 :         d = json_object_get(c, "action");
     560           1 :         assert_non_null(d);
     561           1 :         assert_true(json_is_string(d));
     562           1 :         assert_string_equal("add", json_string_value(d));
     563             : 
     564           1 :         e = json_object_get(c, "values");
     565           1 :         assert_non_null(b);
     566           1 :         assert_true(json_is_array(e));
     567           1 :         assert_int_equal(1, json_array_size(e));
     568             : 
     569           1 :         f = json_array_get(e, 0);
     570           1 :         assert_non_null(f);
     571           1 :         assert_true(json_is_object(f));
     572           1 :         assert_int_equal(1, json_object_size(f));
     573             : 
     574           1 :         g = json_object_get(f, "value");
     575           1 :         assert_non_null(g);
     576           1 :         assert_true(json_is_string(g));
     577           1 :         assert_string_equal("the-value", json_string_value(g));
     578             : 
     579           1 :         json_free(&json);
     580           1 :         TALLOC_FREE(ctx);
     581             : 
     582           1 : }
     583             : 
     584             : /*
     585             :  * unit test of operation_json, that ensures that all the expected
     586             :  * attributes and objects are in the json object.
     587             :  * In this case for an operation performed as the system user.
     588             :  */
     589           1 : static void test_as_system_operation_json(void **state)
     590             : {
     591           1 :         struct ldb_context *ldb = NULL;
     592           1 :         struct ldb_module  *module = NULL;
     593           1 :         struct ldb_request *req = NULL;
     594           1 :         struct ldb_reply *reply = NULL;
     595           1 :         struct audit_private *audit_private = NULL;
     596             : 
     597           1 :         struct tsocket_address *ts = NULL;
     598             : 
     599           1 :         struct auth_session_info *sess = NULL;
     600           1 :         struct auth_session_info *sys_sess = NULL;
     601           1 :         struct security_token *token = NULL;
     602           1 :         struct security_token *sys_token = NULL;
     603           1 :         struct dom_sid sid;
     604           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
     605           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     606           1 :         const char * const SYS_SESSION = "7130cb06-2062-6a1b-409e-3514c26b1998";
     607           1 :         struct GUID session_id;
     608           1 :         struct GUID sys_session_id;
     609             : 
     610           1 :         struct GUID transaction_id;
     611           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     612             : 
     613           1 :         struct ldb_dn *dn = NULL;
     614           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
     615             : 
     616           1 :         struct ldb_message *msg = NULL;
     617             : 
     618           1 :         struct json_object json;
     619           1 :         json_t *audit = NULL;
     620           1 :         json_t *v = NULL;
     621           1 :         json_t *o = NULL;
     622           1 :         json_t *a = NULL;
     623           1 :         json_t *b = NULL;
     624           1 :         json_t *c = NULL;
     625           1 :         json_t *d = NULL;
     626           1 :         json_t *e = NULL;
     627           1 :         json_t *f = NULL;
     628           1 :         json_t *g = NULL;
     629           1 :         time_t before;
     630           1 :         struct timeval tv;
     631           1 :         int rc;
     632             : 
     633             : 
     634           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     635             : 
     636           1 :         ldb = ldb_init(ctx, NULL);
     637             : 
     638           1 :         audit_private = talloc_zero(ctx, struct audit_private);
     639           1 :         GUID_from_string(TRANSACTION, &transaction_id);
     640           1 :         audit_private->transaction_guid = transaction_id;
     641             : 
     642           1 :         module = talloc_zero(ctx, struct ldb_module);
     643           1 :         module->ldb = ldb;
     644           1 :         ldb_module_set_private(module, audit_private);
     645             : 
     646           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
     647           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
     648             : 
     649           1 :         sess = talloc_zero(ctx, struct auth_session_info);
     650           1 :         token = talloc_zero(ctx, struct security_token);
     651           1 :         string_to_sid(&sid, SID);
     652           1 :         token->num_sids = 1;
     653           1 :         token->sids = &sid;
     654           1 :         sess->security_token = token;
     655           1 :         GUID_from_string(SESSION, &session_id);
     656           1 :         sess->unique_session_token = session_id;
     657           1 :         ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, sess);
     658             : 
     659           1 :         sys_sess = talloc_zero(ctx, struct auth_session_info);
     660           1 :         sys_token = talloc_zero(ctx, struct security_token);
     661           1 :         sys_token->num_sids = 1;
     662           1 :         sys_token->sids = discard_const(&global_sid_System);
     663           1 :         sys_sess->security_token = sys_token;
     664           1 :         GUID_from_string(SYS_SESSION, &sys_session_id);
     665           1 :         sess->unique_session_token = sys_session_id;
     666           1 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sys_sess);
     667             : 
     668           1 :         msg = talloc_zero(ctx, struct ldb_message);
     669           1 :         dn = ldb_dn_new(ctx, ldb, DN);
     670           1 :         msg->dn = dn;
     671           1 :         ldb_msg_add_string(msg, "attribute", "the-value");
     672             : 
     673           1 :         req = talloc_zero(ctx, struct ldb_request);
     674           1 :         req->operation =  LDB_ADD;
     675           1 :         req->op.add.message = msg;
     676             : 
     677           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     678           1 :         reply->error = LDB_ERR_OPERATIONS_ERROR;
     679             : 
     680           1 :         rc = gettimeofday(&tv, NULL);
     681           1 :         assert_return_code(rc, errno);
     682           1 :         before = tv.tv_sec;
     683           1 :         json = operation_json(module, req, reply);
     684           1 :         assert_int_equal(3, json_object_size(json.root));
     685             : 
     686           1 :         v = json_object_get(json.root, "type");
     687           1 :         assert_non_null(v);
     688           1 :         assert_string_equal("dsdbChange", json_string_value(v));
     689             : 
     690           1 :         v = json_object_get(json.root, "timestamp");
     691           1 :         assert_non_null(v);
     692           1 :         assert_true(json_is_string(v));
     693           1 :         check_timestamp(before, json_string_value(v));
     694             : 
     695           1 :         audit = json_object_get(json.root, "dsdbChange");
     696           1 :         assert_non_null(audit);
     697           1 :         assert_true(json_is_object(audit));
     698           1 :         assert_int_equal(11, json_object_size(audit));
     699             : 
     700           1 :         o = json_object_get(audit, "version");
     701           1 :         assert_non_null(o);
     702           1 :         check_version(o, OPERATION_MAJOR, OPERATION_MINOR);
     703             : 
     704           1 :         v = json_object_get(audit, "statusCode");
     705           1 :         assert_non_null(v);
     706           1 :         assert_true(json_is_integer(v));
     707           1 :         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
     708             : 
     709           1 :         v = json_object_get(audit, "status");
     710           1 :         assert_non_null(v);
     711           1 :         assert_true(json_is_string(v));
     712           1 :         assert_string_equal("Operations error", json_string_value(v));
     713             : 
     714           1 :         v = json_object_get(audit, "operation");
     715           1 :         assert_non_null(v);
     716           1 :         assert_true(json_is_string(v));
     717           1 :         assert_string_equal("Add", json_string_value(v));
     718             : 
     719           1 :         v = json_object_get(audit, "remoteAddress");
     720           1 :         assert_non_null(v);
     721           1 :         assert_true(json_is_string(v));
     722           1 :         assert_string_equal("ipv4:127.0.0.1:0", json_string_value(v));
     723             : 
     724           1 :         v = json_object_get(audit, "userSid");
     725           1 :         assert_non_null(v);
     726           1 :         assert_true(json_is_string(v));
     727           1 :         assert_string_equal(SID, json_string_value(v));
     728             : 
     729           1 :         v = json_object_get(audit, "performedAsSystem");
     730           1 :         assert_non_null(v);
     731           1 :         assert_true(json_is_boolean(v));
     732           1 :         assert_true(json_is_true(v));
     733             : 
     734           1 :         v = json_object_get(audit, "dn");
     735           1 :         assert_non_null(v);
     736           1 :         assert_true(json_is_string(v));
     737           1 :         assert_string_equal(DN, json_string_value(v));
     738             : 
     739           1 :         v = json_object_get(audit, "transactionId");
     740           1 :         assert_non_null(v);
     741           1 :         assert_true(json_is_string(v));
     742           1 :         assert_string_equal(TRANSACTION, json_string_value(v));
     743             : 
     744           1 :         v = json_object_get(audit, "sessionId");
     745           1 :         assert_non_null(v);
     746           1 :         assert_true(json_is_string(v));
     747           1 :         assert_string_equal(SYS_SESSION, json_string_value(v));
     748             : 
     749           1 :         o = json_object_get(audit, "attributes");
     750           1 :         assert_non_null(v);
     751           1 :         assert_true(json_is_object(o));
     752           1 :         assert_int_equal(1, json_object_size(o));
     753             : 
     754           1 :         a = json_object_get(o, "attribute");
     755           1 :         assert_non_null(a);
     756           1 :         assert_true(json_is_object(a));
     757             : 
     758           1 :         b = json_object_get(a, "actions");
     759           1 :         assert_non_null(b);
     760           1 :         assert_true(json_is_array(b));
     761           1 :         assert_int_equal(1, json_array_size(b));
     762             : 
     763           1 :         c = json_array_get(b, 0);
     764           1 :         assert_non_null(c);
     765           1 :         assert_true(json_is_object(c));
     766             : 
     767           1 :         d = json_object_get(c, "action");
     768           1 :         assert_non_null(d);
     769           1 :         assert_true(json_is_string(d));
     770           1 :         assert_string_equal("add", json_string_value(d));
     771             : 
     772           1 :         e = json_object_get(c, "values");
     773           1 :         assert_non_null(b);
     774           1 :         assert_true(json_is_array(e));
     775           1 :         assert_int_equal(1, json_array_size(e));
     776             : 
     777           1 :         f = json_array_get(e, 0);
     778           1 :         assert_non_null(f);
     779           1 :         assert_true(json_is_object(f));
     780           1 :         assert_int_equal(1, json_object_size(f));
     781             : 
     782           1 :         g = json_object_get(f, "value");
     783           1 :         assert_non_null(g);
     784           1 :         assert_true(json_is_string(g));
     785           1 :         assert_string_equal("the-value", json_string_value(g));
     786             : 
     787           1 :         json_free(&json);
     788           1 :         TALLOC_FREE(ctx);
     789             : 
     790           1 : }
     791             : 
     792             : /*
     793             :  * minimal unit test of password_change_json, that ensures that all the expected
     794             :  * attributes and objects are in the json object.
     795             :  */
     796           1 : static void test_password_change_json_empty(void **state)
     797             : {
     798           1 :         struct ldb_context *ldb = NULL;
     799           1 :         struct ldb_module  *module = NULL;
     800           1 :         struct ldb_request *req = NULL;
     801           1 :         struct ldb_reply *reply = NULL;
     802           1 :         struct audit_private *audit_private = NULL;
     803             : 
     804           1 :         struct json_object json;
     805           1 :         json_t *audit = NULL;
     806           1 :         json_t *v = NULL;
     807           1 :         json_t *o = NULL;
     808           1 :         time_t before;
     809           1 :         struct timeval tv;
     810           1 :         int rc;
     811             : 
     812             : 
     813           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     814             : 
     815           1 :         ldb = ldb_init(ctx, NULL);
     816           1 :         audit_private = talloc_zero(ctx, struct audit_private);
     817             : 
     818           1 :         module = talloc_zero(ctx, struct ldb_module);
     819           1 :         module->ldb = ldb;
     820           1 :         ldb_module_set_private(module, audit_private);
     821             : 
     822           1 :         req = talloc_zero(ctx, struct ldb_request);
     823           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     824           1 :         reply->error = LDB_SUCCESS;
     825             : 
     826           1 :         rc = gettimeofday(&tv, NULL);
     827           1 :         assert_return_code(rc, errno);
     828           1 :         before = tv.tv_sec;
     829           1 :         json = password_change_json(module, req, reply);
     830           1 :         assert_int_equal(3, json_object_size(json.root));
     831             : 
     832             : 
     833           1 :         v = json_object_get(json.root, "type");
     834           1 :         assert_non_null(v);
     835           1 :         assert_string_equal("passwordChange", json_string_value(v));
     836             : 
     837           1 :         v = json_object_get(json.root, "timestamp");
     838           1 :         assert_non_null(v);
     839           1 :         assert_true(json_is_string(v));
     840           1 :         check_timestamp(before, json_string_value(v));
     841             : 
     842           1 :         audit = json_object_get(json.root, "passwordChange");
     843           1 :         assert_non_null(audit);
     844           1 :         assert_true(json_is_object(audit));
     845           1 :         assert_int_equal(10, json_object_size(audit));
     846             : 
     847           1 :         o = json_object_get(audit, "version");
     848           1 :         assert_non_null(o);
     849             : 
     850           1 :         v = json_object_get(audit, "eventId");
     851           1 :         assert_non_null(v);
     852             : 
     853           1 :         v = json_object_get(audit, "statusCode");
     854           1 :         assert_non_null(v);
     855             : 
     856           1 :         v = json_object_get(audit, "status");
     857           1 :         assert_non_null(v);
     858             : 
     859           1 :         v = json_object_get(audit, "remoteAddress");
     860           1 :         assert_non_null(v);
     861             : 
     862           1 :         v = json_object_get(audit, "userSid");
     863           1 :         assert_non_null(v);
     864             : 
     865           1 :         v = json_object_get(audit, "dn");
     866           1 :         assert_non_null(v);
     867             : 
     868           1 :         v = json_object_get(audit, "transactionId");
     869           1 :         assert_non_null(v);
     870             : 
     871           1 :         v = json_object_get(audit, "sessionId");
     872           1 :         assert_non_null(v);
     873             : 
     874           1 :         v = json_object_get(audit, "action");
     875           1 :         assert_non_null(v);
     876             : 
     877           1 :         json_free(&json);
     878           1 :         TALLOC_FREE(ctx);
     879             : 
     880           1 : }
     881             : 
     882             : /*
     883             :  * minimal unit test of password_change_json, that ensures that all the expected
     884             :  * attributes and objects are in the json object.
     885             :  */
     886           1 : static void test_password_change_json(void **state)
     887             : {
     888           1 :         struct ldb_context *ldb = NULL;
     889           1 :         struct ldb_module  *module = NULL;
     890           1 :         struct ldb_request *req = NULL;
     891           1 :         struct ldb_reply *reply = NULL;
     892           1 :         struct audit_private *audit_private = NULL;
     893             : 
     894           1 :         struct tsocket_address *ts = NULL;
     895             : 
     896           1 :         struct auth_session_info *sess = NULL;
     897           1 :         struct security_token *token = NULL;
     898           1 :         struct dom_sid sid;
     899           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
     900           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     901           1 :         struct GUID session_id;
     902             : 
     903           1 :         struct GUID transaction_id;
     904           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     905             : 
     906           1 :         struct ldb_dn *dn = NULL;
     907           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
     908             : 
     909           1 :         struct ldb_message *msg = NULL;
     910             : 
     911           1 :         struct json_object json;
     912           1 :         json_t *audit = NULL;
     913           1 :         json_t *v = NULL;
     914           1 :         json_t *o = NULL;
     915           1 :         time_t before;
     916           1 :         struct timeval tv;
     917           1 :         int rc;
     918             : 
     919           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     920             : 
     921           1 :         ldb = ldb_init(ctx, NULL);
     922             : 
     923           1 :         audit_private = talloc_zero(ctx, struct audit_private);
     924           1 :         GUID_from_string(TRANSACTION, &transaction_id);
     925           1 :         audit_private->transaction_guid = transaction_id;
     926             : 
     927           1 :         module = talloc_zero(ctx, struct ldb_module);
     928           1 :         module->ldb = ldb;
     929           1 :         ldb_module_set_private(module, audit_private);
     930             : 
     931           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
     932           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
     933             : 
     934           1 :         sess = talloc_zero(ctx, struct auth_session_info);
     935           1 :         token = talloc_zero(ctx, struct security_token);
     936           1 :         string_to_sid(&sid, SID);
     937           1 :         token->num_sids = 1;
     938           1 :         token->sids = &sid;
     939           1 :         sess->security_token = token;
     940           1 :         GUID_from_string(SESSION, &session_id);
     941           1 :         sess->unique_session_token = session_id;
     942           1 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
     943             : 
     944           1 :         msg = talloc_zero(ctx, struct ldb_message);
     945           1 :         dn = ldb_dn_new(ctx, ldb, DN);
     946           1 :         msg->dn = dn;
     947           1 :         ldb_msg_add_string(msg, "planTextPassword", "super-secret");
     948             : 
     949           1 :         req = talloc_zero(ctx, struct ldb_request);
     950           1 :         req->operation =  LDB_ADD;
     951           1 :         req->op.add.message = msg;
     952           1 :         reply = talloc_zero(ctx, struct ldb_reply);
     953           1 :         reply->error = LDB_SUCCESS;
     954             : 
     955           1 :         rc = gettimeofday(&tv, NULL);
     956           1 :         assert_return_code(rc, errno);
     957           1 :         before = tv.tv_sec;
     958           1 :         json = password_change_json(module, req, reply);
     959           1 :         assert_int_equal(3, json_object_size(json.root));
     960             : 
     961             : 
     962           1 :         v = json_object_get(json.root, "type");
     963           1 :         assert_non_null(v);
     964           1 :         assert_string_equal("passwordChange", json_string_value(v));
     965             : 
     966           1 :         v = json_object_get(json.root, "timestamp");
     967           1 :         assert_non_null(v);
     968           1 :         assert_true(json_is_string(v));
     969           1 :         check_timestamp(before, json_string_value(v));
     970             : 
     971           1 :         audit = json_object_get(json.root, "passwordChange");
     972           1 :         assert_non_null(audit);
     973           1 :         assert_true(json_is_object(audit));
     974           1 :         assert_int_equal(10, json_object_size(audit));
     975             : 
     976           1 :         o = json_object_get(audit, "version");
     977           1 :         assert_non_null(o);
     978           1 :         check_version(o, PASSWORD_MAJOR,PASSWORD_MINOR);
     979             : 
     980           1 :         v = json_object_get(audit, "eventId");
     981           1 :         assert_non_null(v);
     982           1 :         assert_true(json_is_integer(v));
     983           1 :         assert_int_equal(EVT_ID_PASSWORD_RESET, json_integer_value(v));
     984             : 
     985           1 :         v = json_object_get(audit, "statusCode");
     986           1 :         assert_non_null(v);
     987           1 :         assert_true(json_is_integer(v));
     988           1 :         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
     989             : 
     990           1 :         v = json_object_get(audit, "status");
     991           1 :         assert_non_null(v);
     992           1 :         assert_true(json_is_string(v));
     993           1 :         assert_string_equal("Success", json_string_value(v));
     994             : 
     995           1 :         v = json_object_get(audit, "remoteAddress");
     996           1 :         assert_non_null(v);
     997           1 :         assert_true(json_is_string(v));
     998           1 :         assert_string_equal("ipv4:127.0.0.1:0", json_string_value(v));
     999             : 
    1000           1 :         v = json_object_get(audit, "userSid");
    1001           1 :         assert_non_null(v);
    1002           1 :         assert_true(json_is_string(v));
    1003           1 :         assert_string_equal(SID, json_string_value(v));
    1004             : 
    1005           1 :         v = json_object_get(audit, "dn");
    1006           1 :         assert_non_null(v);
    1007           1 :         assert_true(json_is_string(v));
    1008           1 :         assert_string_equal(DN, json_string_value(v));
    1009             : 
    1010           1 :         v = json_object_get(audit, "transactionId");
    1011           1 :         assert_non_null(v);
    1012           1 :         assert_true(json_is_string(v));
    1013           1 :         assert_string_equal(TRANSACTION, json_string_value(v));
    1014             : 
    1015           1 :         v = json_object_get(audit, "sessionId");
    1016           1 :         assert_non_null(v);
    1017           1 :         assert_true(json_is_string(v));
    1018           1 :         assert_string_equal(SESSION, json_string_value(v));
    1019             : 
    1020           1 :         v = json_object_get(audit, "action");
    1021           1 :         assert_non_null(v);
    1022           1 :         assert_true(json_is_string(v));
    1023           1 :         assert_string_equal("Reset", json_string_value(v));
    1024             : 
    1025           1 :         json_free(&json);
    1026           1 :         TALLOC_FREE(ctx);
    1027             : 
    1028           1 : }
    1029             : 
    1030             : 
    1031             : /*
    1032             :  * minimal unit test of transaction_json, that ensures that all the expected
    1033             :  * attributes and objects are in the json object.
    1034             :  */
    1035           1 : static void test_transaction_json(void **state)
    1036             : {
    1037             : 
    1038           1 :         struct GUID guid;
    1039           1 :         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1040             : 
    1041           1 :         struct json_object json;
    1042           1 :         json_t *audit = NULL;
    1043           1 :         json_t *v = NULL;
    1044           1 :         json_t *o = NULL;
    1045           1 :         time_t before;
    1046           1 :         struct timeval tv;
    1047           1 :         int rc;
    1048             : 
    1049           1 :         GUID_from_string(GUID, &guid);
    1050             : 
    1051           1 :         rc = gettimeofday(&tv, NULL);
    1052           1 :         assert_return_code(rc, errno);
    1053           1 :         before = tv.tv_sec;
    1054           1 :         json = transaction_json("delete", &guid, 10000099);
    1055             : 
    1056           1 :         assert_int_equal(3, json_object_size(json.root));
    1057             : 
    1058             : 
    1059           1 :         v = json_object_get(json.root, "type");
    1060           1 :         assert_non_null(v);
    1061           1 :         assert_string_equal("dsdbTransaction", json_string_value(v));
    1062             : 
    1063           1 :         v = json_object_get(json.root, "timestamp");
    1064           1 :         assert_non_null(v);
    1065           1 :         assert_true(json_is_string(v));
    1066           1 :         check_timestamp(before, json_string_value(v));
    1067             : 
    1068           1 :         audit = json_object_get(json.root, "dsdbTransaction");
    1069           1 :         assert_non_null(audit);
    1070           1 :         assert_true(json_is_object(audit));
    1071           1 :         assert_int_equal(4, json_object_size(audit));
    1072             : 
    1073           1 :         o = json_object_get(audit, "version");
    1074           1 :         assert_non_null(o);
    1075           1 :         check_version(o, TRANSACTION_MAJOR, TRANSACTION_MINOR);
    1076             : 
    1077           1 :         v = json_object_get(audit, "transactionId");
    1078           1 :         assert_non_null(v);
    1079           1 :         assert_true(json_is_string(v));
    1080           1 :         assert_string_equal(GUID, json_string_value(v));
    1081             : 
    1082           1 :         v = json_object_get(audit, "action");
    1083           1 :         assert_non_null(v);
    1084           1 :         assert_true(json_is_string(v));
    1085           1 :         assert_string_equal("delete", json_string_value(v));
    1086             : 
    1087           1 :         v = json_object_get(audit, "duration");
    1088           1 :         assert_non_null(v);
    1089           1 :         assert_true(json_is_integer(v));
    1090           1 :         assert_int_equal(10000099, json_integer_value(v));
    1091             : 
    1092           1 :         json_free(&json);
    1093             : 
    1094           1 : }
    1095             : 
    1096             : /*
    1097             :  * minimal unit test of commit_failure_json, that ensures that all the
    1098             :  * expected attributes and objects are in the json object.
    1099             :  */
    1100           1 : static void test_commit_failure_json(void **state)
    1101             : {
    1102             : 
    1103           1 :         struct GUID guid;
    1104           1 :         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1105             : 
    1106           1 :         struct json_object json;
    1107           1 :         json_t *audit = NULL;
    1108           1 :         json_t *v = NULL;
    1109           1 :         json_t *o = NULL;
    1110           1 :         time_t before;
    1111           1 :         struct timeval tv;
    1112           1 :         int rc;
    1113             : 
    1114           1 :         GUID_from_string(GUID, &guid);
    1115             : 
    1116           1 :         rc = gettimeofday(&tv, NULL);
    1117           1 :         assert_return_code(rc, errno);
    1118           1 :         before = tv.tv_sec;
    1119           1 :         json = commit_failure_json(
    1120             :                 "prepare",
    1121             :                 987876,
    1122             :                 LDB_ERR_OPERATIONS_ERROR,
    1123             :                 "because",
    1124             :                 &guid);
    1125             : 
    1126           1 :         assert_int_equal(3, json_object_size(json.root));
    1127             : 
    1128             : 
    1129           1 :         v = json_object_get(json.root, "type");
    1130           1 :         assert_non_null(v);
    1131           1 :         assert_string_equal("dsdbTransaction", json_string_value(v));
    1132             : 
    1133           1 :         v = json_object_get(json.root, "timestamp");
    1134           1 :         assert_non_null(v);
    1135           1 :         assert_true(json_is_string(v));
    1136           1 :         check_timestamp(before, json_string_value(v));
    1137             : 
    1138           1 :         audit = json_object_get(json.root, "dsdbTransaction");
    1139           1 :         assert_non_null(audit);
    1140           1 :         assert_true(json_is_object(audit));
    1141           1 :         assert_int_equal(7, json_object_size(audit));
    1142             : 
    1143           1 :         o = json_object_get(audit, "version");
    1144           1 :         assert_non_null(o);
    1145           1 :         check_version(o, TRANSACTION_MAJOR, TRANSACTION_MINOR);
    1146             : 
    1147           1 :         v = json_object_get(audit, "transactionId");
    1148           1 :         assert_non_null(v);
    1149           1 :         assert_true(json_is_string(v));
    1150           1 :         assert_string_equal(GUID, json_string_value(v));
    1151             : 
    1152           1 :         v = json_object_get(audit, "action");
    1153           1 :         assert_non_null(v);
    1154           1 :         assert_true(json_is_string(v));
    1155           1 :         assert_string_equal("prepare", json_string_value(v));
    1156             : 
    1157           1 :         v = json_object_get(audit, "statusCode");
    1158           1 :         assert_non_null(v);
    1159           1 :         assert_true(json_is_integer(v));
    1160           1 :         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
    1161             : 
    1162           1 :         v = json_object_get(audit, "status");
    1163           1 :         assert_non_null(v);
    1164           1 :         assert_true(json_is_string(v));
    1165           1 :         assert_string_equal("Operations error", json_string_value(v));
    1166           1 :         v = json_object_get(audit, "status");
    1167           1 :         assert_non_null(v);
    1168             : 
    1169           1 :         v = json_object_get(audit, "reason");
    1170           1 :         assert_non_null(v);
    1171           1 :         assert_true(json_is_string(v));
    1172           1 :         assert_string_equal("because", json_string_value(v));
    1173             : 
    1174           1 :         v = json_object_get(audit, "duration");
    1175           1 :         assert_non_null(v);
    1176           1 :         assert_true(json_is_integer(v));
    1177           1 :         assert_int_equal(987876, json_integer_value(v));
    1178             : 
    1179           1 :         json_free(&json);
    1180             : 
    1181           1 : }
    1182             : 
    1183             : /*
    1184             :  * minimal unit test of replicated_update_json, that ensures that all the
    1185             :  * expected attributes and objects are in the json object.
    1186             :  */
    1187           1 : static void test_replicated_update_json_empty(void **state)
    1188             : {
    1189           1 :         struct ldb_context *ldb = NULL;
    1190           1 :         struct ldb_module  *module = NULL;
    1191           1 :         struct ldb_request *req = NULL;
    1192           1 :         struct ldb_reply *reply = NULL;
    1193           1 :         struct audit_private *audit_private = NULL;
    1194           1 :         struct dsdb_extended_replicated_objects *ro = NULL;
    1195           1 :         struct repsFromTo1 *source_dsa = NULL;
    1196             : 
    1197           1 :         struct json_object json;
    1198           1 :         json_t *audit = NULL;
    1199           1 :         json_t *v = NULL;
    1200           1 :         json_t *o = NULL;
    1201           1 :         time_t before;
    1202           1 :         struct timeval tv;
    1203           1 :         int rc;
    1204             : 
    1205             : 
    1206           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1207             : 
    1208           1 :         ldb = ldb_init(ctx, NULL);
    1209           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1210             : 
    1211           1 :         module = talloc_zero(ctx, struct ldb_module);
    1212           1 :         module->ldb = ldb;
    1213           1 :         ldb_module_set_private(module, audit_private);
    1214             : 
    1215           1 :         source_dsa = talloc_zero(ctx, struct repsFromTo1);
    1216           1 :         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
    1217           1 :         ro->source_dsa = source_dsa;
    1218           1 :         req = talloc_zero(ctx, struct ldb_request);
    1219           1 :         req->op.extended.data = ro;
    1220           1 :         req->operation = LDB_EXTENDED;
    1221           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    1222           1 :         reply->error = LDB_SUCCESS;
    1223             : 
    1224           1 :         rc = gettimeofday(&tv, NULL);
    1225           1 :         assert_return_code(rc, errno);
    1226           1 :         before = tv.tv_sec;
    1227           1 :         json = replicated_update_json(module, req, reply);
    1228           1 :         assert_int_equal(3, json_object_size(json.root));
    1229             : 
    1230             : 
    1231           1 :         v = json_object_get(json.root, "type");
    1232           1 :         assert_non_null(v);
    1233           1 :         assert_string_equal("replicatedUpdate", json_string_value(v));
    1234             : 
    1235           1 :         v = json_object_get(json.root, "timestamp");
    1236           1 :         assert_non_null(v);
    1237           1 :         assert_true(json_is_string(v));
    1238           1 :         check_timestamp(before, json_string_value(v));
    1239             : 
    1240           1 :         audit = json_object_get(json.root, "replicatedUpdate");
    1241           1 :         assert_non_null(audit);
    1242           1 :         assert_true(json_is_object(audit));
    1243           1 :         assert_int_equal(11, json_object_size(audit));
    1244             : 
    1245           1 :         o = json_object_get(audit, "version");
    1246           1 :         assert_non_null(o);
    1247           1 :         check_version(o, REPLICATION_MAJOR, REPLICATION_MINOR);
    1248             : 
    1249           1 :         v = json_object_get(audit, "statusCode");
    1250           1 :         assert_non_null(v);
    1251           1 :         assert_true(json_is_integer(v));
    1252           1 :         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
    1253             : 
    1254           1 :         v = json_object_get(audit, "status");
    1255           1 :         assert_non_null(v);
    1256           1 :         assert_true(json_is_string(v));
    1257           1 :         assert_string_equal("Success", json_string_value(v));
    1258             : 
    1259           1 :         v = json_object_get(audit, "transactionId");
    1260           1 :         assert_non_null(v);
    1261           1 :         assert_true(json_is_string(v));
    1262           1 :         assert_string_equal(
    1263             :                 "00000000-0000-0000-0000-000000000000",
    1264             :                 json_string_value(v));
    1265             : 
    1266           1 :         v = json_object_get(audit, "objectCount");
    1267           1 :         assert_non_null(v);
    1268           1 :         assert_true(json_is_integer(v));
    1269           1 :         assert_int_equal(0, json_integer_value(v));
    1270             : 
    1271           1 :         v = json_object_get(audit, "linkCount");
    1272           1 :         assert_non_null(v);
    1273           1 :         assert_true(json_is_integer(v));
    1274           1 :         assert_int_equal(0, json_integer_value(v));
    1275             : 
    1276           1 :         v = json_object_get(audit, "partitionDN");
    1277           1 :         assert_non_null(v);
    1278           1 :         assert_true(json_is_null(v));
    1279             : 
    1280           1 :         v = json_object_get(audit, "error");
    1281           1 :         assert_non_null(v);
    1282           1 :         assert_true(json_is_string(v));
    1283           1 :         assert_string_equal(
    1284             :                 "The operation completed successfully.",
    1285             :                 json_string_value(v));
    1286             : 
    1287           1 :         v = json_object_get(audit, "errorCode");
    1288           1 :         assert_non_null(v);
    1289           1 :         assert_true(json_is_integer(v));
    1290           1 :         assert_int_equal(0, json_integer_value(v));
    1291             : 
    1292           1 :         v = json_object_get(audit, "sourceDsa");
    1293           1 :         assert_non_null(v);
    1294           1 :         assert_true(json_is_string(v));
    1295           1 :         assert_string_equal(
    1296             :                 "00000000-0000-0000-0000-000000000000",
    1297             :                 json_string_value(v));
    1298             : 
    1299           1 :         v = json_object_get(audit, "invocationId");
    1300           1 :         assert_non_null(v);
    1301           1 :         assert_true(json_is_string(v));
    1302           1 :         assert_string_equal(
    1303             :                 "00000000-0000-0000-0000-000000000000",
    1304             :                 json_string_value(v));
    1305             : 
    1306           1 :         json_free(&json);
    1307           1 :         TALLOC_FREE(ctx);
    1308             : 
    1309           1 : }
    1310             : 
    1311             : /*
    1312             :  * unit test of replicated_update_json, that ensures that all the expected
    1313             :  * attributes and objects are in the json object.
    1314             :  */
    1315           1 : static void test_replicated_update_json(void **state)
    1316             : {
    1317           1 :         struct ldb_context *ldb = NULL;
    1318           1 :         struct ldb_module  *module = NULL;
    1319           1 :         struct ldb_request *req = NULL;
    1320           1 :         struct ldb_reply *reply = NULL;
    1321           1 :         struct audit_private *audit_private = NULL;
    1322           1 :         struct dsdb_extended_replicated_objects *ro = NULL;
    1323           1 :         struct repsFromTo1 *source_dsa = NULL;
    1324             : 
    1325           1 :         struct GUID transaction_id;
    1326           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1327             : 
    1328           1 :         struct ldb_dn *dn = NULL;
    1329           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
    1330             : 
    1331           1 :         struct GUID source_dsa_obj_guid;
    1332           1 :         const char *const SOURCE_DSA = "7130cb06-2062-6a1b-409e-3514c26b1793";
    1333             : 
    1334           1 :         struct GUID invocation_id;
    1335           1 :         const char *const INVOCATION_ID =
    1336             :                 "7130cb06-2062-6a1b-409e-3514c26b1893";
    1337           1 :         struct json_object json;
    1338           1 :         json_t *audit = NULL;
    1339           1 :         json_t *v = NULL;
    1340           1 :         json_t *o = NULL;
    1341           1 :         time_t before;
    1342           1 :         struct timeval tv;
    1343           1 :         int rc;
    1344             : 
    1345             : 
    1346           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1347             : 
    1348           1 :         ldb = ldb_init(ctx, NULL);
    1349             : 
    1350           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1351           1 :         GUID_from_string(TRANSACTION, &transaction_id);
    1352           1 :         audit_private->transaction_guid = transaction_id;
    1353             : 
    1354           1 :         module = talloc_zero(ctx, struct ldb_module);
    1355           1 :         module->ldb = ldb;
    1356           1 :         ldb_module_set_private(module, audit_private);
    1357             : 
    1358           1 :         dn = ldb_dn_new(ctx, ldb, DN);
    1359           1 :         GUID_from_string(SOURCE_DSA, &source_dsa_obj_guid);
    1360           1 :         GUID_from_string(INVOCATION_ID, &invocation_id);
    1361           1 :         source_dsa = talloc_zero(ctx, struct repsFromTo1);
    1362           1 :         source_dsa->source_dsa_obj_guid = source_dsa_obj_guid;
    1363           1 :         source_dsa->source_dsa_invocation_id = invocation_id;
    1364             : 
    1365           1 :         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
    1366           1 :         ro->source_dsa = source_dsa;
    1367           1 :         ro->num_objects = 808;
    1368           1 :         ro->linked_attributes_count = 2910;
    1369           1 :         ro->partition_dn = dn;
    1370           1 :         ro->error = WERR_NOT_SUPPORTED;
    1371             : 
    1372             : 
    1373           1 :         req = talloc_zero(ctx, struct ldb_request);
    1374           1 :         req->op.extended.data = ro;
    1375           1 :         req->operation = LDB_EXTENDED;
    1376             : 
    1377           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    1378           1 :         reply->error = LDB_ERR_NO_SUCH_OBJECT;
    1379             : 
    1380           1 :         rc = gettimeofday(&tv, NULL);
    1381           1 :         assert_return_code(rc, errno);
    1382           1 :         before = tv.tv_sec;
    1383           1 :         json = replicated_update_json(module, req, reply);
    1384           1 :         assert_int_equal(3, json_object_size(json.root));
    1385             : 
    1386             : 
    1387           1 :         v = json_object_get(json.root, "type");
    1388           1 :         assert_non_null(v);
    1389           1 :         assert_string_equal("replicatedUpdate", json_string_value(v));
    1390             : 
    1391           1 :         v = json_object_get(json.root, "timestamp");
    1392           1 :         assert_non_null(v);
    1393           1 :         assert_true(json_is_string(v));
    1394           1 :         check_timestamp(before, json_string_value(v));
    1395             : 
    1396           1 :         audit = json_object_get(json.root, "replicatedUpdate");
    1397           1 :         assert_non_null(audit);
    1398           1 :         assert_true(json_is_object(audit));
    1399           1 :         assert_int_equal(11, json_object_size(audit));
    1400             : 
    1401           1 :         o = json_object_get(audit, "version");
    1402           1 :         assert_non_null(o);
    1403           1 :         check_version(o, REPLICATION_MAJOR, REPLICATION_MINOR);
    1404             : 
    1405           1 :         v = json_object_get(audit, "statusCode");
    1406           1 :         assert_non_null(v);
    1407           1 :         assert_true(json_is_integer(v));
    1408           1 :         assert_int_equal(LDB_ERR_NO_SUCH_OBJECT, json_integer_value(v));
    1409             : 
    1410           1 :         v = json_object_get(audit, "status");
    1411           1 :         assert_non_null(v);
    1412           1 :         assert_true(json_is_string(v));
    1413           1 :         assert_string_equal("No such object", json_string_value(v));
    1414             : 
    1415           1 :         v = json_object_get(audit, "transactionId");
    1416           1 :         assert_non_null(v);
    1417           1 :         assert_true(json_is_string(v));
    1418           1 :         assert_string_equal(TRANSACTION, json_string_value(v));
    1419             : 
    1420           1 :         v = json_object_get(audit, "objectCount");
    1421           1 :         assert_non_null(v);
    1422           1 :         assert_true(json_is_integer(v));
    1423           1 :         assert_int_equal(808, json_integer_value(v));
    1424             : 
    1425           1 :         v = json_object_get(audit, "linkCount");
    1426           1 :         assert_non_null(v);
    1427           1 :         assert_true(json_is_integer(v));
    1428           1 :         assert_int_equal(2910, json_integer_value(v));
    1429             : 
    1430           1 :         v = json_object_get(audit, "partitionDN");
    1431           1 :         assert_non_null(v);
    1432           1 :         assert_true(json_is_string(v));
    1433           1 :         assert_string_equal(DN, json_string_value(v));
    1434             : 
    1435           1 :         v = json_object_get(audit, "error");
    1436           1 :         assert_non_null(v);
    1437           1 :         assert_true(json_is_string(v));
    1438           1 :         assert_string_equal(
    1439             :                 "The request is not supported.",
    1440             :                 json_string_value(v));
    1441             : 
    1442           1 :         v = json_object_get(audit, "errorCode");
    1443           1 :         assert_non_null(v);
    1444           1 :         assert_true(json_is_integer(v));
    1445           1 :         assert_int_equal(W_ERROR_V(WERR_NOT_SUPPORTED), json_integer_value(v));
    1446             : 
    1447           1 :         v = json_object_get(audit, "sourceDsa");
    1448           1 :         assert_non_null(v);
    1449           1 :         assert_true(json_is_string(v));
    1450           1 :         assert_string_equal(SOURCE_DSA, json_string_value(v));
    1451             : 
    1452           1 :         v = json_object_get(audit, "invocationId");
    1453           1 :         assert_non_null(v);
    1454           1 :         assert_true(json_is_string(v));
    1455           1 :         assert_string_equal(INVOCATION_ID, json_string_value(v));
    1456             : 
    1457           1 :         json_free(&json);
    1458           1 :         TALLOC_FREE(ctx);
    1459             : 
    1460           1 : }
    1461             : 
    1462             : /*
    1463             :  * minimal unit test of operation_human_readable, that ensures that all the
    1464             :  * expected attributes and objects are in the json object.
    1465             :  */
    1466           1 : static void test_operation_hr_empty(void **state)
    1467             : {
    1468           1 :         struct ldb_context *ldb = NULL;
    1469           1 :         struct ldb_module  *module = NULL;
    1470           1 :         struct ldb_request *req = NULL;
    1471           1 :         struct ldb_reply *reply = NULL;
    1472           1 :         struct audit_private *audit_private = NULL;
    1473             : 
    1474           1 :         char *line = NULL;
    1475           1 :         const char *rs = NULL;
    1476           1 :         regex_t regex;
    1477             : 
    1478           1 :         int ret;
    1479             : 
    1480           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1481             : 
    1482           1 :         ldb = ldb_init(ctx, NULL);
    1483           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1484             : 
    1485           1 :         module = talloc_zero(ctx, struct ldb_module);
    1486           1 :         module->ldb = ldb;
    1487           1 :         ldb_module_set_private(module, audit_private);
    1488             : 
    1489           1 :         req = talloc_zero(ctx, struct ldb_request);
    1490           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    1491           1 :         reply->error = LDB_SUCCESS;
    1492             : 
    1493           1 :         line = operation_human_readable(ctx, module, req, reply);
    1494           1 :         assert_non_null(line);
    1495             : 
    1496             :         /*
    1497             :          * We ignore the timestamp to make this test a little easier
    1498             :          * to write.
    1499             :          */
    1500           1 :         rs =    "\\[Search] at \\["
    1501             :                 "[^[]*"
    1502             :                 "\\] status \\[Success\\] remote host \\[Unknown\\]"
    1503             :                 " SID \\[(NULL SID)\\] DN \\[(null)\\]";
    1504             : 
    1505           1 :         ret = regcomp(&regex, rs, 0);
    1506           1 :         assert_int_equal(0, ret);
    1507             : 
    1508           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    1509           1 :         assert_int_equal(0, ret);
    1510             : 
    1511           1 :         regfree(&regex);
    1512           1 :         TALLOC_FREE(ctx);
    1513             : 
    1514           1 : }
    1515             : 
    1516             : /*
    1517             :  * unit test of operation_json, that ensures that all the expected
    1518             :  * attributes and objects are in the json object.
    1519             :  */
    1520           1 : static void test_operation_hr(void **state)
    1521             : {
    1522           1 :         struct ldb_context *ldb = NULL;
    1523           1 :         struct ldb_module  *module = NULL;
    1524           1 :         struct ldb_request *req = NULL;
    1525           1 :         struct ldb_reply *reply = NULL;
    1526           1 :         struct audit_private *audit_private = NULL;
    1527             : 
    1528           1 :         struct tsocket_address *ts = NULL;
    1529             : 
    1530           1 :         struct auth_session_info *sess = NULL;
    1531           1 :         struct security_token *token = NULL;
    1532           1 :         struct dom_sid sid;
    1533           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1534           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1535           1 :         struct GUID session_id;
    1536             : 
    1537           1 :         struct GUID transaction_id;
    1538           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1539             : 
    1540           1 :         struct ldb_dn *dn = NULL;
    1541           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
    1542             : 
    1543           1 :         struct ldb_message *msg = NULL;
    1544             : 
    1545           1 :         char *line = NULL;
    1546           1 :         const char *rs = NULL;
    1547           1 :         regex_t regex;
    1548             : 
    1549           1 :         int ret;
    1550             : 
    1551             : 
    1552           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1553             : 
    1554           1 :         ldb = ldb_init(ctx, NULL);
    1555             : 
    1556           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1557           1 :         GUID_from_string(TRANSACTION, &transaction_id);
    1558           1 :         audit_private->transaction_guid = transaction_id;
    1559             : 
    1560           1 :         module = talloc_zero(ctx, struct ldb_module);
    1561           1 :         module->ldb = ldb;
    1562           1 :         ldb_module_set_private(module, audit_private);
    1563             : 
    1564           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
    1565           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
    1566             : 
    1567           1 :         sess = talloc_zero(ctx, struct auth_session_info);
    1568           1 :         token = talloc_zero(ctx, struct security_token);
    1569           1 :         string_to_sid(&sid, SID);
    1570           1 :         token->num_sids = 1;
    1571           1 :         token->sids = &sid;
    1572           1 :         sess->security_token = token;
    1573           1 :         GUID_from_string(SESSION, &session_id);
    1574           1 :         sess->unique_session_token = session_id;
    1575           1 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
    1576             : 
    1577           1 :         msg = talloc_zero(ctx, struct ldb_message);
    1578           1 :         dn = ldb_dn_new(ctx, ldb, DN);
    1579           1 :         msg->dn = dn;
    1580           1 :         ldb_msg_add_string(msg, "attribute", "the-value");
    1581             : 
    1582           1 :         req = talloc_zero(ctx, struct ldb_request);
    1583           1 :         req->operation =  LDB_ADD;
    1584           1 :         req->op.add.message = msg;
    1585           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    1586           1 :         reply->error = LDB_SUCCESS;
    1587             : 
    1588           1 :         line = operation_human_readable(ctx, module, req, reply);
    1589           1 :         assert_non_null(line);
    1590             : 
    1591             :         /*
    1592             :          * We ignore the timestamp to make this test a little easier
    1593             :          * to write.
    1594             :          */
    1595           1 :         rs =    "\\[Add\\] at \\["
    1596             :                 "[^]]*"
    1597             :                 "\\] status \\[Success\\] "
    1598             :                 "remote host \\[ipv4:127.0.0.1:0\\] "
    1599             :                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
    1600             :                 "DN \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\] "
    1601             :                 "attributes \\[attribute \\[the-value\\]\\]";
    1602             : 
    1603           1 :         ret = regcomp(&regex, rs, 0);
    1604           1 :         assert_int_equal(0, ret);
    1605             : 
    1606           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    1607           1 :         assert_int_equal(0, ret);
    1608             : 
    1609           1 :         regfree(&regex);
    1610           1 :         TALLOC_FREE(ctx);
    1611           1 : }
    1612             : 
    1613             : /*
    1614             :  * unit test of operation_json, that ensures that all the expected
    1615             :  * attributes and objects are in the json object.
    1616             :  * In this case the operation is being performed in a system session.
    1617             :  */
    1618           1 : static void test_as_system_operation_hr(void **state)
    1619             : {
    1620           1 :         struct ldb_context *ldb = NULL;
    1621           1 :         struct ldb_module  *module = NULL;
    1622           1 :         struct ldb_request *req = NULL;
    1623           1 :         struct ldb_reply *reply = NULL;
    1624           1 :         struct audit_private *audit_private = NULL;
    1625             : 
    1626           1 :         struct tsocket_address *ts = NULL;
    1627             : 
    1628           1 :         struct auth_session_info *sess = NULL;
    1629           1 :         struct auth_session_info *sys_sess = NULL;
    1630           1 :         struct security_token *token = NULL;
    1631           1 :         struct security_token *sys_token = NULL;
    1632           1 :         struct dom_sid sid;
    1633           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1634           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1635           1 :         const char * const SYS_SESSION = "7130cb06-2062-6a1b-409e-3514c26b1999";
    1636           1 :         struct GUID session_id;
    1637           1 :         struct GUID sys_session_id;
    1638             : 
    1639           1 :         struct GUID transaction_id;
    1640           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1641             : 
    1642           1 :         struct ldb_dn *dn = NULL;
    1643           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
    1644             : 
    1645           1 :         struct ldb_message *msg = NULL;
    1646             : 
    1647           1 :         char *line = NULL;
    1648           1 :         const char *rs = NULL;
    1649           1 :         regex_t regex;
    1650             : 
    1651           1 :         int ret;
    1652             : 
    1653             : 
    1654           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1655             : 
    1656           1 :         ldb = ldb_init(ctx, NULL);
    1657             : 
    1658           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1659           1 :         GUID_from_string(TRANSACTION, &transaction_id);
    1660           1 :         audit_private->transaction_guid = transaction_id;
    1661             : 
    1662           1 :         module = talloc_zero(ctx, struct ldb_module);
    1663           1 :         module->ldb = ldb;
    1664           1 :         ldb_module_set_private(module, audit_private);
    1665             : 
    1666           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
    1667           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
    1668             : 
    1669           1 :         sess = talloc_zero(ctx, struct auth_session_info);
    1670           1 :         token = talloc_zero(ctx, struct security_token);
    1671           1 :         string_to_sid(&sid, SID);
    1672           1 :         token->num_sids = 1;
    1673           1 :         token->sids = &sid;
    1674           1 :         sess->security_token = token;
    1675           1 :         GUID_from_string(SESSION, &session_id);
    1676           1 :         sess->unique_session_token = session_id;
    1677           1 :         ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, sess);
    1678             : 
    1679           1 :         sys_sess = talloc_zero(ctx, struct auth_session_info);
    1680           1 :         sys_token = talloc_zero(ctx, struct security_token);
    1681           1 :         sys_token->num_sids = 1;
    1682           1 :         sys_token->sids = discard_const(&global_sid_System);
    1683           1 :         sys_sess->security_token = sys_token;
    1684           1 :         GUID_from_string(SYS_SESSION, &sys_session_id);
    1685           1 :         sess->unique_session_token = sys_session_id;
    1686           1 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sys_sess);
    1687             : 
    1688           1 :         msg = talloc_zero(ctx, struct ldb_message);
    1689           1 :         dn = ldb_dn_new(ctx, ldb, DN);
    1690           1 :         msg->dn = dn;
    1691           1 :         ldb_msg_add_string(msg, "attribute", "the-value");
    1692             : 
    1693           1 :         req = talloc_zero(ctx, struct ldb_request);
    1694           1 :         req->operation =  LDB_ADD;
    1695           1 :         req->op.add.message = msg;
    1696           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    1697           1 :         reply->error = LDB_SUCCESS;
    1698             : 
    1699           1 :         line = operation_human_readable(ctx, module, req, reply);
    1700           1 :         assert_non_null(line);
    1701             : 
    1702             :         /*
    1703             :          * We ignore the timestamp to make this test a little easier
    1704             :          * to write.
    1705             :          */
    1706           1 :         rs =    "\\[Add\\] at \\["
    1707             :                 "[^]]*"
    1708             :                 "\\] status \\[Success\\] "
    1709             :                 "remote host \\[ipv4:127.0.0.1:0\\] "
    1710             :                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
    1711             :                 "DN \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\] "
    1712             :                 "attributes \\[attribute \\[the-value\\]\\]";
    1713             : 
    1714           1 :         ret = regcomp(&regex, rs, 0);
    1715           1 :         assert_int_equal(0, ret);
    1716             : 
    1717           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    1718           1 :         assert_int_equal(0, ret);
    1719             : 
    1720           1 :         regfree(&regex);
    1721           1 :         TALLOC_FREE(ctx);
    1722           1 : }
    1723             : 
    1724             : /*
    1725             :  * minimal unit test of password_change_json, that ensures that all the expected
    1726             :  * attributes and objects are in the json object.
    1727             :  */
    1728           1 : static void test_password_change_hr_empty(void **state)
    1729             : {
    1730           1 :         struct ldb_context *ldb = NULL;
    1731           1 :         struct ldb_module  *module = NULL;
    1732           1 :         struct ldb_request *req = NULL;
    1733           1 :         struct ldb_reply *reply = NULL;
    1734           1 :         struct audit_private *audit_private = NULL;
    1735             : 
    1736           1 :         char *line = NULL;
    1737           1 :         const char *rs = NULL;
    1738           1 :         regex_t regex;
    1739           1 :         int ret;
    1740             : 
    1741           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1742             : 
    1743           1 :         ldb = ldb_init(ctx, NULL);
    1744           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1745             : 
    1746           1 :         module = talloc_zero(ctx, struct ldb_module);
    1747           1 :         module->ldb = ldb;
    1748           1 :         ldb_module_set_private(module, audit_private);
    1749             : 
    1750           1 :         req = talloc_zero(ctx, struct ldb_request);
    1751           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    1752           1 :         reply->error = LDB_SUCCESS;
    1753             : 
    1754           1 :         line = password_change_human_readable(ctx, module, req, reply);
    1755           1 :         assert_non_null(line);
    1756             : 
    1757             :         /*
    1758             :          * We ignore the timestamp to make this test a little easier
    1759             :          * to write.
    1760             :          */
    1761           1 :         rs =    "\\[Reset] at \\["
    1762             :                 "[^[]*"
    1763             :                 "\\] status \\[Success\\] remote host \\[Unknown\\]"
    1764             :                 " SID \\[(NULL SID)\\] DN \\[(null)\\]";
    1765             : 
    1766           1 :         ret = regcomp(&regex, rs, 0);
    1767           1 :         assert_int_equal(0, ret);
    1768             : 
    1769           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    1770           1 :         assert_int_equal(0, ret);
    1771             : 
    1772           1 :         regfree(&regex);
    1773           1 :         TALLOC_FREE(ctx);
    1774           1 : }
    1775             : 
    1776             : /*
    1777             :  * minimal unit test of password_change_json, that ensures that all the expected
    1778             :  * attributes and objects are in the json object.
    1779             :  */
    1780           1 : static void test_password_change_hr(void **state)
    1781             : {
    1782           1 :         struct ldb_context *ldb = NULL;
    1783           1 :         struct ldb_module  *module = NULL;
    1784           1 :         struct ldb_request *req = NULL;
    1785           1 :         struct ldb_reply *reply = NULL;
    1786           1 :         struct audit_private *audit_private = NULL;
    1787             : 
    1788           1 :         struct tsocket_address *ts = NULL;
    1789             : 
    1790           1 :         struct auth_session_info *sess = NULL;
    1791           1 :         struct security_token *token = NULL;
    1792           1 :         struct dom_sid sid;
    1793           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1794           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1795           1 :         struct GUID session_id;
    1796             : 
    1797           1 :         struct GUID transaction_id;
    1798           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1799             : 
    1800           1 :         struct ldb_dn *dn = NULL;
    1801           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
    1802             : 
    1803           1 :         struct ldb_message *msg = NULL;
    1804             : 
    1805           1 :         char *line = NULL;
    1806           1 :         const char *rs = NULL;
    1807           1 :         regex_t regex;
    1808           1 :         int ret;
    1809             : 
    1810           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1811             : 
    1812           1 :         ldb = ldb_init(ctx, NULL);
    1813             : 
    1814           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1815           1 :         GUID_from_string(TRANSACTION, &transaction_id);
    1816           1 :         audit_private->transaction_guid = transaction_id;
    1817             : 
    1818           1 :         module = talloc_zero(ctx, struct ldb_module);
    1819           1 :         module->ldb = ldb;
    1820           1 :         ldb_module_set_private(module, audit_private);
    1821             : 
    1822           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
    1823           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
    1824             : 
    1825           1 :         sess = talloc_zero(ctx, struct auth_session_info);
    1826           1 :         token = talloc_zero(ctx, struct security_token);
    1827           1 :         string_to_sid(&sid, SID);
    1828           1 :         token->num_sids = 1;
    1829           1 :         token->sids = &sid;
    1830           1 :         sess->security_token = token;
    1831           1 :         GUID_from_string(SESSION, &session_id);
    1832           1 :         sess->unique_session_token = session_id;
    1833           1 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
    1834             : 
    1835           1 :         msg = talloc_zero(ctx, struct ldb_message);
    1836           1 :         dn = ldb_dn_new(ctx, ldb, DN);
    1837           1 :         msg->dn = dn;
    1838           1 :         ldb_msg_add_string(msg, "planTextPassword", "super-secret");
    1839             : 
    1840           1 :         req = talloc_zero(ctx, struct ldb_request);
    1841           1 :         req->operation =  LDB_ADD;
    1842           1 :         req->op.add.message = msg;
    1843           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    1844           1 :         reply->error = LDB_SUCCESS;
    1845             : 
    1846           1 :         line = password_change_human_readable(ctx, module, req, reply);
    1847           1 :         assert_non_null(line);
    1848             : 
    1849             :         /*
    1850             :          * We ignore the timestamp to make this test a little easier
    1851             :          * to write.
    1852             :          */
    1853           1 :         rs =    "\\[Reset\\] at \\["
    1854             :                 "[^[]*"
    1855             :                 "\\] status \\[Success\\] "
    1856             :                 "remote host \\[ipv4:127.0.0.1:0\\] "
    1857             :                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
    1858             :                 "DN \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\]";
    1859             : 
    1860           1 :         ret = regcomp(&regex, rs, 0);
    1861           1 :         assert_int_equal(0, ret);
    1862             : 
    1863           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    1864           1 :         assert_int_equal(0, ret);
    1865             : 
    1866           1 :         regfree(&regex);
    1867           1 :         TALLOC_FREE(ctx);
    1868             : 
    1869           1 : }
    1870             : 
    1871             : /*
    1872             :  * minimal unit test of transaction_json, that ensures that all the expected
    1873             :  * attributes and objects are in the json object.
    1874             :  */
    1875           1 : static void test_transaction_hr(void **state)
    1876             : {
    1877             : 
    1878           1 :         struct GUID guid;
    1879           1 :         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1880             : 
    1881           1 :         char *line = NULL;
    1882           1 :         const char *rs = NULL;
    1883           1 :         regex_t regex;
    1884           1 :         int ret;
    1885             : 
    1886           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1887             : 
    1888           1 :         GUID_from_string(GUID, &guid);
    1889             : 
    1890           1 :         line = transaction_human_readable(ctx, "delete", 23);
    1891           1 :         assert_non_null(line);
    1892             : 
    1893             :         /*
    1894             :          * We ignore the timestamp to make this test a little easier
    1895             :          * to write.
    1896             :          */
    1897           1 :         rs = "\\[delete] at \\[[^[]*\\] duration \\[23\\]";
    1898             : 
    1899           1 :         ret = regcomp(&regex, rs, 0);
    1900           1 :         assert_int_equal(0, ret);
    1901             : 
    1902           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    1903           1 :         assert_int_equal(0, ret);
    1904             : 
    1905           1 :         regfree(&regex);
    1906           1 :         TALLOC_FREE(ctx);
    1907             : 
    1908           1 : }
    1909             : 
    1910             : /*
    1911             :  * minimal unit test of commit_failure_hr, that ensures
    1912             :  * that all the expected content is in the log entry.
    1913             :  */
    1914           1 : static void test_commit_failure_hr(void **state)
    1915             : {
    1916             : 
    1917           1 :         struct GUID guid;
    1918           1 :         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1919             : 
    1920           1 :         char *line = NULL;
    1921           1 :         const char *rs = NULL;
    1922           1 :         regex_t regex;
    1923           1 :         int ret;
    1924             : 
    1925           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1926             : 
    1927           1 :         GUID_from_string(GUID, &guid);
    1928             : 
    1929           1 :         line = commit_failure_human_readable(
    1930             :                 ctx,
    1931             :                 "commit",
    1932             :                 789345,
    1933             :                 LDB_ERR_OPERATIONS_ERROR,
    1934             :                 "because");
    1935             : 
    1936           1 :         assert_non_null(line);
    1937             : 
    1938             :         /*
    1939             :          * We ignore the timestamp to make this test a little easier
    1940             :          * to write.
    1941             :          */
    1942           1 :         rs = "\\[commit\\] at \\[[^[]*\\] duration \\[789345\\] "
    1943             :              "status \\[1\\] reason \\[because\\]";
    1944             : 
    1945           1 :         ret = regcomp(&regex, rs, 0);
    1946           1 :         assert_int_equal(0, ret);
    1947             : 
    1948           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    1949           1 :         assert_int_equal(0, ret);
    1950             : 
    1951           1 :         regfree(&regex);
    1952           1 :         TALLOC_FREE(ctx);
    1953           1 : }
    1954             : 
    1955           1 : static void test_add_transaction_id(void **state)
    1956             : {
    1957           1 :         struct ldb_module  *module = NULL;
    1958           1 :         struct ldb_request *req = NULL;
    1959           1 :         struct audit_private *audit_private = NULL;
    1960           1 :         struct GUID guid;
    1961           1 :         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1962           1 :         struct ldb_control * control = NULL;
    1963           1 :         int status;
    1964             : 
    1965           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1966             : 
    1967           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    1968           1 :         GUID_from_string(GUID, &guid);
    1969           1 :         audit_private->transaction_guid = guid;
    1970             : 
    1971           1 :         module = talloc_zero(ctx, struct ldb_module);
    1972           1 :         ldb_module_set_private(module, audit_private);
    1973             : 
    1974           1 :         req = talloc_zero(ctx, struct ldb_request);
    1975             : 
    1976           1 :         status = add_transaction_id(module, req);
    1977           1 :         assert_int_equal(LDB_SUCCESS, status);
    1978             : 
    1979           1 :         control = ldb_request_get_control(
    1980             :                 req,
    1981             :                 DSDB_CONTROL_TRANSACTION_IDENTIFIER_OID);
    1982           1 :         assert_non_null(control);
    1983           1 :         assert_memory_equal(
    1984             :                 &audit_private->transaction_guid,
    1985             :                 control->data,
    1986             :                 sizeof(struct GUID));
    1987             : 
    1988           1 :         TALLOC_FREE(ctx);
    1989           1 : }
    1990             : 
    1991           1 : static void test_log_attributes(void **state)
    1992             : {
    1993           1 :         struct ldb_message *msg = NULL;
    1994             : 
    1995           1 :         char *buf = NULL;
    1996           1 :         char *str = NULL;
    1997           1 :         char lv[MAX_LENGTH+2];
    1998           1 :         char ex[MAX_LENGTH+80];
    1999             : 
    2000           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    2001             : 
    2002             : 
    2003             :         /*
    2004             :          * Test an empty message
    2005             :          * Should get empty attributes representation.
    2006             :          */
    2007           1 :         buf = talloc_zero(ctx, char);
    2008           1 :         msg = talloc_zero(ctx, struct ldb_message);
    2009             : 
    2010           1 :         str = log_attributes(ctx, buf, LDB_ADD, msg);
    2011           1 :         assert_string_equal("", str);
    2012             : 
    2013           1 :         TALLOC_FREE(str);
    2014           1 :         TALLOC_FREE(msg);
    2015             : 
    2016             :         /*
    2017             :          * Test a message with a single secret attribute
    2018             :          */
    2019           1 :         buf = talloc_zero(ctx, char);
    2020           1 :         msg = talloc_zero(ctx, struct ldb_message);
    2021           1 :         ldb_msg_add_string(msg, "clearTextPassword", "secret");
    2022             : 
    2023           1 :         str = log_attributes(ctx, buf, LDB_ADD, msg);
    2024           1 :         assert_string_equal(
    2025             :                 "clearTextPassword [REDACTED SECRET ATTRIBUTE]",
    2026             :                 str);
    2027           1 :         TALLOC_FREE(str);
    2028             :         /*
    2029             :          * Test as a modify message, should add an action
    2030             :          * action will be unknown as there are no ACL's set
    2031             :          */
    2032           1 :         buf = talloc_zero(ctx, char);
    2033           1 :         str = log_attributes(ctx, buf, LDB_MODIFY, msg);
    2034           1 :         assert_string_equal(
    2035             :                 "unknown: clearTextPassword [REDACTED SECRET ATTRIBUTE]",
    2036             :                 str);
    2037             : 
    2038           1 :         TALLOC_FREE(str);
    2039           1 :         TALLOC_FREE(msg);
    2040             : 
    2041             :         /*
    2042             :          * Test a message with a single attribute, single valued attribute
    2043             :          */
    2044           1 :         buf = talloc_zero(ctx, char);
    2045           1 :         msg = talloc_zero(ctx, struct ldb_message);
    2046           1 :         ldb_msg_add_string(msg, "attribute", "value");
    2047             : 
    2048           1 :         str = log_attributes(ctx, buf, LDB_ADD, msg);
    2049           1 :         assert_string_equal(
    2050             :                 "attribute [value]",
    2051             :                 str);
    2052             : 
    2053           1 :         TALLOC_FREE(str);
    2054           1 :         TALLOC_FREE(msg);
    2055             : 
    2056             :         /*
    2057             :          * Test a message with a single attribute, single valued attribute
    2058             :          * And as a modify
    2059             :          */
    2060           1 :         buf = talloc_zero(ctx, char);
    2061           1 :         msg = talloc_zero(ctx, struct ldb_message);
    2062           1 :         ldb_msg_add_string(msg, "attribute", "value");
    2063             : 
    2064           1 :         str = log_attributes(ctx, buf, LDB_MODIFY, msg);
    2065           1 :         assert_string_equal(
    2066             :                 "unknown: attribute [value]",
    2067             :                 str);
    2068             : 
    2069           1 :         TALLOC_FREE(str);
    2070           1 :         TALLOC_FREE(msg);
    2071             : 
    2072             :         /*
    2073             :          * Test a message with multiple attributes and a multi-valued attribute
    2074             :          *
    2075             :          */
    2076           1 :         buf = talloc_zero(ctx, char);
    2077           1 :         msg = talloc_zero(ctx, struct ldb_message);
    2078           1 :         ldb_msg_add_string(msg, "attribute01", "value01");
    2079           1 :         ldb_msg_add_string(msg, "attribute02", "value02");
    2080           1 :         ldb_msg_add_string(msg, "attribute02", "value03");
    2081             : 
    2082           1 :         str = log_attributes(ctx, buf, LDB_MODIFY, msg);
    2083           1 :         assert_string_equal(
    2084             :                 "unknown: attribute01 [value01] "
    2085             :                 "unknown: attribute02 [value02] [value03]",
    2086             :                 str);
    2087             : 
    2088           1 :         TALLOC_FREE(str);
    2089           1 :         TALLOC_FREE(msg);
    2090             : 
    2091             :         /*
    2092             :          * Test a message with a single attribute, single valued attribute
    2093             :          * with a non printable character. Should be base64 encoded
    2094             :          */
    2095           1 :         buf = talloc_zero(ctx, char);
    2096           1 :         msg = talloc_zero(ctx, struct ldb_message);
    2097           1 :         ldb_msg_add_string(msg, "attribute", "value\n");
    2098             : 
    2099           1 :         str = log_attributes(ctx, buf, LDB_ADD, msg);
    2100           1 :         assert_string_equal("attribute {dmFsdWUK}", str);
    2101             : 
    2102           1 :         TALLOC_FREE(str);
    2103           1 :         TALLOC_FREE(msg);
    2104             : 
    2105             :         /*
    2106             :          * Test a message with a single valued attribute
    2107             :          * with more than MAX_LENGTH characters, should be truncated with
    2108             :          * trailing ...
    2109             :          */
    2110           1 :         buf = talloc_zero(ctx, char);
    2111           1 :         msg = talloc_zero(ctx, struct ldb_message);
    2112           1 :         memset(lv, '\0', sizeof(lv));
    2113           1 :         memset(lv, 'x', MAX_LENGTH+1);
    2114           1 :         ldb_msg_add_string(msg, "attribute", lv);
    2115             : 
    2116           1 :         str = log_attributes(ctx, buf, LDB_ADD, msg);
    2117           1 :         snprintf(ex, sizeof(ex), "attribute [%.*s...]", MAX_LENGTH, lv);
    2118           1 :         assert_string_equal(ex, str);
    2119             : 
    2120           1 :         TALLOC_FREE(str);
    2121           1 :         TALLOC_FREE(msg);
    2122             : 
    2123           1 :         TALLOC_FREE(ctx);
    2124           1 : }
    2125             : 
    2126             : /*
    2127             :  * minimal unit test of replicated_update_human_readable
    2128             :  */
    2129           1 : static void test_replicated_update_hr_empty(void **state)
    2130             : {
    2131           1 :         struct ldb_context *ldb = NULL;
    2132           1 :         struct ldb_module  *module = NULL;
    2133           1 :         struct ldb_request *req = NULL;
    2134           1 :         struct ldb_reply *reply = NULL;
    2135           1 :         struct audit_private *audit_private = NULL;
    2136           1 :         struct dsdb_extended_replicated_objects *ro = NULL;
    2137           1 :         struct repsFromTo1 *source_dsa = NULL;
    2138             : 
    2139           1 :         const char* line = NULL;
    2140           1 :         const char *rs = NULL;
    2141           1 :         regex_t regex;
    2142           1 :         int ret;
    2143             : 
    2144           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    2145             : 
    2146           1 :         ldb = ldb_init(ctx, NULL);
    2147           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    2148             : 
    2149           1 :         module = talloc_zero(ctx, struct ldb_module);
    2150           1 :         module->ldb = ldb;
    2151           1 :         ldb_module_set_private(module, audit_private);
    2152             : 
    2153           1 :         source_dsa = talloc_zero(ctx, struct repsFromTo1);
    2154           1 :         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
    2155           1 :         ro->source_dsa = source_dsa;
    2156           1 :         req = talloc_zero(ctx, struct ldb_request);
    2157           1 :         req->op.extended.data = ro;
    2158           1 :         req->operation = LDB_EXTENDED;
    2159           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    2160           1 :         reply->error = LDB_SUCCESS;
    2161             : 
    2162           1 :         line = replicated_update_human_readable(ctx, module, req, reply);
    2163           1 :         assert_non_null(line);
    2164             :         /*
    2165             :          * We ignore the timestamp to make this test a little easier
    2166             :          * to write.
    2167             :          */
    2168           1 :         rs =    "at \\[[^[]*\\] "
    2169             :                 "status \\[Success\\] "
    2170             :                 "error \\[The operation completed successfully.\\] "
    2171             :                 "partition \\[(null)\\] objects \\[0\\] links \\[0\\] "
    2172             :                 "object \\[00000000-0000-0000-0000-000000000000\\] "
    2173             :                 "invocation \\[00000000-0000-0000-0000-000000000000\\]";
    2174             : 
    2175           1 :         ret = regcomp(&regex, rs, 0);
    2176           1 :         assert_int_equal(0, ret);
    2177             : 
    2178           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    2179           1 :         assert_int_equal(0, ret);
    2180             : 
    2181           1 :         regfree(&regex);
    2182           1 :         TALLOC_FREE(ctx);
    2183             : 
    2184           1 : }
    2185             : 
    2186             : /*
    2187             :  * unit test of replicated_update_human_readable
    2188             :  */
    2189           1 : static void test_replicated_update_hr(void **state)
    2190             : {
    2191           1 :         struct ldb_context *ldb = NULL;
    2192           1 :         struct ldb_module  *module = NULL;
    2193           1 :         struct ldb_request *req = NULL;
    2194           1 :         struct ldb_reply *reply = NULL;
    2195           1 :         struct audit_private *audit_private = NULL;
    2196           1 :         struct dsdb_extended_replicated_objects *ro = NULL;
    2197           1 :         struct repsFromTo1 *source_dsa = NULL;
    2198             : 
    2199           1 :         struct GUID transaction_id;
    2200           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    2201             : 
    2202           1 :         struct ldb_dn *dn = NULL;
    2203           1 :         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
    2204             : 
    2205           1 :         struct GUID source_dsa_obj_guid;
    2206           1 :         const char *const SOURCE_DSA = "7130cb06-2062-6a1b-409e-3514c26b1793";
    2207             : 
    2208           1 :         struct GUID invocation_id;
    2209           1 :         const char *const INVOCATION_ID =
    2210             :                 "7130cb06-2062-6a1b-409e-3514c26b1893";
    2211             : 
    2212           1 :         const char* line = NULL;
    2213           1 :         const char *rs = NULL;
    2214           1 :         regex_t regex;
    2215           1 :         int ret;
    2216             : 
    2217             : 
    2218           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    2219             : 
    2220           1 :         ldb = ldb_init(ctx, NULL);
    2221             : 
    2222           1 :         audit_private = talloc_zero(ctx, struct audit_private);
    2223           1 :         GUID_from_string(TRANSACTION, &transaction_id);
    2224           1 :         audit_private->transaction_guid = transaction_id;
    2225             : 
    2226           1 :         module = talloc_zero(ctx, struct ldb_module);
    2227           1 :         module->ldb = ldb;
    2228           1 :         ldb_module_set_private(module, audit_private);
    2229             : 
    2230           1 :         dn = ldb_dn_new(ctx, ldb, DN);
    2231           1 :         GUID_from_string(SOURCE_DSA, &source_dsa_obj_guid);
    2232           1 :         GUID_from_string(INVOCATION_ID, &invocation_id);
    2233           1 :         source_dsa = talloc_zero(ctx, struct repsFromTo1);
    2234           1 :         source_dsa->source_dsa_obj_guid = source_dsa_obj_guid;
    2235           1 :         source_dsa->source_dsa_invocation_id = invocation_id;
    2236             : 
    2237           1 :         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
    2238           1 :         ro->source_dsa = source_dsa;
    2239           1 :         ro->num_objects = 808;
    2240           1 :         ro->linked_attributes_count = 2910;
    2241           1 :         ro->partition_dn = dn;
    2242           1 :         ro->error = WERR_NOT_SUPPORTED;
    2243             : 
    2244             : 
    2245           1 :         req = talloc_zero(ctx, struct ldb_request);
    2246           1 :         req->op.extended.data = ro;
    2247           1 :         req->operation = LDB_EXTENDED;
    2248             : 
    2249           1 :         reply = talloc_zero(ctx, struct ldb_reply);
    2250           1 :         reply->error = LDB_ERR_NO_SUCH_OBJECT;
    2251             : 
    2252           1 :         line = replicated_update_human_readable(ctx, module, req, reply);
    2253           1 :         assert_non_null(line);
    2254             : 
    2255             :         /*
    2256             :          * We ignore the timestamp to make this test a little easier
    2257             :          * to write.
    2258             :          */
    2259           1 :         rs =    "at \\[[^[]*\\] "
    2260             :                 "status \\[No such object\\] "
    2261             :                 "error \\[The request is not supported.\\] "
    2262             :                 "partition \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\] "
    2263             :                 "objects \\[808\\] links \\[2910\\] "
    2264             :                 "object \\[7130cb06-2062-6a1b-409e-3514c26b1793\\] "
    2265             :                 "invocation \\[7130cb06-2062-6a1b-409e-3514c26b1893\\]";
    2266             : 
    2267           1 :         ret = regcomp(&regex, rs, 0);
    2268           1 :         assert_int_equal(0, ret);
    2269             : 
    2270           1 :         ret = regexec(&regex, line, 0, NULL, 0);
    2271           1 :         assert_int_equal(0, ret);
    2272             : 
    2273           1 :         regfree(&regex);
    2274           1 :         TALLOC_FREE(ctx);
    2275           1 : }
    2276             : 
    2277           1 : int main(void) {
    2278           1 :         const struct CMUnitTest tests[] = {
    2279             :                 cmocka_unit_test(test_has_password_changed),
    2280             :                 cmocka_unit_test(test_get_password_action),
    2281             :                 cmocka_unit_test(test_operation_json_empty),
    2282             :                 cmocka_unit_test(test_operation_json),
    2283             :                 cmocka_unit_test(test_as_system_operation_json),
    2284             :                 cmocka_unit_test(test_password_change_json_empty),
    2285             :                 cmocka_unit_test(test_password_change_json),
    2286             :                 cmocka_unit_test(test_transaction_json),
    2287             :                 cmocka_unit_test(test_commit_failure_json),
    2288             :                 cmocka_unit_test(test_replicated_update_json_empty),
    2289             :                 cmocka_unit_test(test_replicated_update_json),
    2290             :                 cmocka_unit_test(test_add_transaction_id),
    2291             :                 cmocka_unit_test(test_operation_hr_empty),
    2292             :                 cmocka_unit_test(test_operation_hr),
    2293             :                 cmocka_unit_test(test_as_system_operation_hr),
    2294             :                 cmocka_unit_test(test_password_change_hr_empty),
    2295             :                 cmocka_unit_test(test_password_change_hr),
    2296             :                 cmocka_unit_test(test_transaction_hr),
    2297             :                 cmocka_unit_test(test_commit_failure_hr),
    2298             :                 cmocka_unit_test(test_log_attributes),
    2299             :                 cmocka_unit_test(test_replicated_update_hr_empty),
    2300             :                 cmocka_unit_test(test_replicated_update_hr),
    2301             :         };
    2302             : 
    2303           1 :         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
    2304           1 :         return cmocka_run_group_tests(tests, NULL, NULL);
    2305             : }

Generated by: LCOV version 1.14