LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules/tests - test_group_audit.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 904 951 95.1 %
Date: 2024-04-21 15:09:00 Functions: 28 28 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unit tests for the dsdb group auditing code in group_audit.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_group_audit_log_module_init(const char *version);
      27             : #include "../group_audit.c"
      28             : 
      29             : #include "lib/ldb/include/ldb_private.h"
      30             : #include <regex.h>
      31             : 
      32             : /*
      33             :  * Mock version of dsdb_search_one
      34             :  */
      35             : struct ldb_dn *g_basedn = NULL;
      36             : enum ldb_scope g_scope;
      37             : const char * const *g_attrs = NULL;
      38             : uint32_t g_dsdb_flags;
      39             : const char *g_exp_fmt;
      40             : const char *g_dn = NULL;
      41             : int g_status = LDB_SUCCESS;
      42             : struct ldb_result *g_result = NULL;
      43             : 
      44           2 : int dsdb_search_one(struct ldb_context *ldb,
      45             :                     TALLOC_CTX *mem_ctx,
      46             :                     struct ldb_message **msg,
      47             :                     struct ldb_dn *basedn,
      48             :                     enum ldb_scope scope,
      49             :                     const char * const *attrs,
      50             :                     uint32_t dsdb_flags,
      51             :                     const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(8, 9)
      52             : {
      53           2 :         struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, g_dn);
      54           2 :         struct ldb_message *m = talloc_zero(mem_ctx, struct ldb_message);
      55           2 :         m->dn = dn;
      56           2 :         *msg = m;
      57             : 
      58           2 :         g_basedn = basedn;
      59           2 :         g_scope = scope;
      60           2 :         g_attrs = attrs;
      61           2 :         g_dsdb_flags = dsdb_flags;
      62           2 :         g_exp_fmt = exp_fmt;
      63             : 
      64           2 :         return g_status;
      65             : }
      66             : 
      67           2 : int dsdb_module_search_dn(
      68             :         struct ldb_module *module,
      69             :         TALLOC_CTX *mem_ctx,
      70             :         struct ldb_result **res,
      71             :         struct ldb_dn *basedn,
      72             :         const char * const *attrs,
      73             :         uint32_t dsdb_flags,
      74             :         struct ldb_request *parent)
      75             : {
      76             : 
      77           2 :         g_basedn = basedn;
      78           2 :         g_attrs = attrs;
      79           2 :         g_dsdb_flags = dsdb_flags;
      80             : 
      81           2 :         *res = g_result;
      82             : 
      83           2 :         return g_status;
      84             : }
      85             : /*
      86             :  * Mock version of audit_log_json
      87             :  */
      88             : 
      89             : #define MAX_EXPECTED_MESSAGES 16
      90             : static struct json_object messages[MAX_EXPECTED_MESSAGES];
      91             : static size_t messages_sent = 0;
      92             : 
      93          11 : void audit_message_send(
      94             :         struct imessaging_context *msg_ctx,
      95             :         const char *server_name,
      96             :         uint32_t message_type,
      97             :         struct json_object *message)
      98             : {
      99          11 :         messages[messages_sent].root = json_deep_copy(message->root);
     100          11 :         messages[messages_sent].valid = message->valid;
     101          11 :         messages_sent++;
     102          11 : }
     103             : 
     104             : #define check_group_change_message(m, u, a, e)                                 \
     105             :         _check_group_change_message(m, u, a, e, __FILE__, __LINE__);
     106             : /*
     107             :  * declare the internal cmocka cm_print_error so that we can output messages
     108             :  * in sub unit format
     109             :  */
     110             : void cm_print_error(const char * const format, ...);
     111             : 
     112             : /*
     113             :  * Validate a group change JSON audit message
     114             :  *
     115             :  * It should contain 3 elements.
     116             :  * Have a type of "groupChange"
     117             :  * Have a groupChange element
     118             :  *
     119             :  * The group change element should have 10 elements.
     120             :  *
     121             :  * There should be a user element matching the expected value
     122             :  * There should be an action matching the expected value
     123             :  */
     124          11 : static void _check_group_change_message(const int message,
     125             :                                         const char *user,
     126             :                                         const char *action,
     127             :                                         enum event_id_type event_id,
     128             :                                         const char *file,
     129             :                                         const int line)
     130             : {
     131          11 :         struct json_object json;
     132          11 :         json_t *audit = NULL;
     133          11 :         json_t *v = NULL;
     134          11 :         const char* value;
     135          11 :         int int_value;
     136          11 :         int cmp;
     137             : 
     138          11 :         json = messages[message];
     139             : 
     140             :         /*
     141             :          * Validate the root JSON element
     142             :          * check the number of elements
     143             :          */
     144          11 :         if (json_object_size(json.root) != 3) {
     145           0 :                 cm_print_error(
     146             :                     "Unexpected number of elements in root %zu != %d\n",
     147             :                     json_object_size(json.root),
     148             :                     3);
     149           0 :                 _fail(file, line);
     150             :         }
     151             : 
     152             :         /*
     153             :          * Check the type element
     154             :          */
     155          11 :         v = json_object_get(json.root, "type");
     156          11 :         if (v == NULL) {
     157           0 :                 cm_print_error( "No \"type\" element\n");
     158           0 :                 _fail(file, line);
     159             :         }
     160             : 
     161          11 :         value = json_string_value(v);
     162          11 :         cmp = strcmp("groupChange", value);
     163          11 :         if (cmp != 0) {
     164           0 :                 cm_print_error(
     165             :                     "Unexpected type \"%s\" != \"groupChange\"\n",
     166             :                     value);
     167           0 :                 _fail(file, line);
     168             :         }
     169             : 
     170             : 
     171          11 :         audit = json_object_get(json.root, "groupChange");
     172          11 :         if (audit == NULL) {
     173           0 :                 cm_print_error("No groupChange element\n");
     174           0 :                 _fail(file, line);
     175             :         }
     176             : 
     177             :         /*
     178             :          * Validate the groupChange element
     179             :          */
     180          11 :         if ((event_id == EVT_ID_NONE && json_object_size(audit) != 10) ||
     181           9 :             (event_id != EVT_ID_NONE && json_object_size(audit) != 11)) {
     182           0 :                 cm_print_error("Unexpected number of elements in groupChange "
     183             :                                "%zu != %d\n",
     184             :                                json_object_size(audit),
     185             :                                11);
     186           0 :                 _fail(file, line);
     187             :         }
     188             :         /*
     189             :          * Validate the user element
     190             :          */
     191          11 :         v = json_object_get(audit, "user");
     192          11 :         if (v == NULL) {
     193           0 :                 cm_print_error( "No user element\n");
     194           0 :                 _fail(file, line);
     195             :         }
     196             : 
     197          11 :         value = json_string_value(v);
     198          11 :         cmp = strcmp(user, value);
     199          11 :         if (cmp != 0) {
     200           0 :                 cm_print_error(
     201             :                     "Unexpected user name \"%s\" != \"%s\"\n",
     202             :                     value,
     203             :                     user);
     204           0 :                 _fail(file, line);
     205             :         }
     206             :         /*
     207             :          * Validate the action element
     208             :          */
     209          11 :         v = json_object_get(audit, "action");
     210          11 :         if (v == NULL) {
     211           0 :                 cm_print_error( "No action element\n");
     212           0 :                 _fail(file, line);
     213             :         }
     214             : 
     215          11 :         value = json_string_value(v);
     216          11 :         cmp = strcmp(action, value);
     217          11 :         if (cmp != 0) {
     218           0 :                 print_error(
     219             :                     "Unexpected action \"%s\" != \"%s\"\n",
     220             :                     value,
     221             :                     action);
     222           0 :                 _fail(file, line);
     223             :         }
     224             : 
     225             :         /*
     226             :          * Validate the eventId element
     227             :          */
     228          11 :         v = json_object_get(audit, "eventId");
     229          11 :         if (event_id == EVT_ID_NONE) {
     230           2 :                 if (v != NULL) {
     231           0 :                         int_value = json_integer_value(v);
     232           0 :                         cm_print_error("Unexpected eventId \"%d\", it should "
     233             :                                        "NOT be present",
     234             :                                        int_value);
     235           0 :                         _fail(file, line);
     236             :                 }
     237             :         }
     238             :         else {
     239           9 :                 if (v == NULL) {
     240           0 :                         cm_print_error("No eventId element\n");
     241           0 :                         _fail(file, line);
     242             :                 }
     243             : 
     244           9 :                 int_value = json_integer_value(v);
     245           9 :                 if (int_value != event_id) {
     246           0 :                         cm_print_error("Unexpected eventId \"%d\" != \"%d\"\n",
     247             :                                        int_value,
     248             :                                        event_id);
     249           0 :                         _fail(file, line);
     250             :                 }
     251             :         }
     252          11 : }
     253             : 
     254             : #define check_timestamp(b, t)\
     255             :         _check_timestamp(b, t, __FILE__, __LINE__);
     256             : /*
     257             :  * Test helper to check ISO 8601 timestamps for validity
     258             :  */
     259           3 : static void _check_timestamp(
     260             :         time_t before,
     261             :         const char *timestamp,
     262             :         const char *file,
     263             :         const int line)
     264             : {
     265           3 :         int rc;
     266           3 :         int usec, tz;
     267           3 :         char c[2];
     268           3 :         struct tm tm;
     269           3 :         time_t after;
     270           3 :         time_t actual;
     271           3 :         struct timeval tv;
     272             : 
     273             : 
     274           3 :         rc = gettimeofday(&tv, NULL);
     275           3 :         assert_return_code(rc, errno);
     276           3 :         after = tv.tv_sec;
     277             : 
     278             :         /*
     279             :          * Convert the ISO 8601 timestamp into a time_t
     280             :          * Note for convenience we ignore the value of the microsecond
     281             :          * part of the time stamp.
     282             :          */
     283           3 :         rc = sscanf(
     284             :                 timestamp,
     285             :                 "%4d-%2d-%2dT%2d:%2d:%2d.%6d%1c%4d",
     286             :                 &tm.tm_year,
     287             :                 &tm.tm_mon,
     288             :                 &tm.tm_mday,
     289             :                 &tm.tm_hour,
     290             :                 &tm.tm_min,
     291             :                 &tm.tm_sec,
     292             :                 &usec,
     293             :                 c,
     294             :                 &tz);
     295           3 :         assert_int_equal(9, rc);
     296           3 :         tm.tm_year = tm.tm_year - 1900;
     297           3 :         tm.tm_mon = tm.tm_mon - 1;
     298           3 :         tm.tm_isdst = -1;
     299           3 :         actual = mktime(&tm);
     300             : 
     301             :         /*
     302             :          * The time stamp should be before <= actual <= after
     303             :          */
     304           3 :         if (difftime(actual, before) < 0) {
     305           0 :                 char buffer[40];
     306           0 :                 strftime(buffer,
     307             :                          sizeof(buffer)-1,
     308             :                          "%Y-%m-%dT%T",
     309           0 :                          localtime(&before));
     310           0 :                 cm_print_error(
     311             :                     "time stamp \"%s\" is before start time \"%s\"\n",
     312             :                     timestamp,
     313             :                     buffer);
     314           0 :                 _fail(file, line);
     315             :         }
     316           3 :         if (difftime(after, actual) < 0) {
     317           0 :                 char buffer[40];
     318           0 :                 strftime(buffer,
     319             :                          sizeof(buffer)-1,
     320             :                          "%Y-%m-%dT%T",
     321           0 :                          localtime(&after));
     322           0 :                 cm_print_error(
     323             :                     "time stamp \"%s\" is after finish time \"%s\"\n",
     324             :                     timestamp,
     325             :                     buffer);
     326           0 :                 _fail(file, line);
     327             :         }
     328           3 : }
     329             : 
     330             : #define check_version(v, m, n)\
     331             :         _check_version(v, m, n, __FILE__, __LINE__);
     332             : /*
     333             :  * Test helper to validate a version object.
     334             :  */
     335           3 : static void _check_version(
     336             :         struct json_t *version,
     337             :         int major,
     338             :         int minor,
     339             :         const char* file,
     340             :         const int line)
     341             : {
     342           3 :         struct json_t *v = NULL;
     343           3 :         int value;
     344             : 
     345           3 :         if (!json_is_object(version)) {
     346           0 :                 cm_print_error("version is not a JSON object\n");
     347           0 :                 _fail(file, line);
     348             :         }
     349             : 
     350           3 :         if (json_object_size(version) != 2) {
     351           0 :                 cm_print_error(
     352             :                     "Unexpected number of elements in version %zu != %d\n",
     353             :                     json_object_size(version),
     354             :                     2);
     355           0 :                 _fail(file, line);
     356             :         }
     357             : 
     358             :         /*
     359             :          * Validate the major version number element
     360             :          */
     361           3 :         v = json_object_get(version, "major");
     362           3 :         if (v == NULL) {
     363           0 :                 cm_print_error( "No major element\n");
     364           0 :                 _fail(file, line);
     365             :         }
     366             : 
     367           3 :         value = json_integer_value(v);
     368           3 :         if (value != major) {
     369           0 :                 print_error(
     370             :                     "Unexpected major version number \"%d\" != \"%d\"\n",
     371             :                     value,
     372             :                     major);
     373           0 :                 _fail(file, line);
     374             :         }
     375             : 
     376             :         /*
     377             :          * Validate the minor version number element
     378             :          */
     379           3 :         v = json_object_get(version, "minor");
     380           3 :         if (v == NULL) {
     381           0 :                 cm_print_error( "No minor element\n");
     382           0 :                 _fail(file, line);
     383             :         }
     384             : 
     385           3 :         value = json_integer_value(v);
     386           3 :         if (value != minor) {
     387           0 :                 print_error(
     388             :                     "Unexpected minor version number \"%d\" != \"%d\"\n",
     389             :                     value,
     390             :                     minor);
     391           0 :                 _fail(file, line);
     392             :         }
     393           3 : }
     394             : 
     395             : /*
     396             :  * Test helper to insert a transaction_id into a request.
     397             :  */
     398          13 : static void add_transaction_id(struct ldb_request *req, const char *id)
     399             : {
     400          13 :         struct GUID guid;
     401          13 :         struct dsdb_control_transaction_identifier *transaction_id = NULL;
     402             : 
     403          13 :         transaction_id = talloc_zero(
     404             :                 req,
     405             :                 struct dsdb_control_transaction_identifier);
     406          13 :         assert_non_null(transaction_id);
     407          13 :         GUID_from_string(id, &guid);
     408          13 :         transaction_id->transaction_guid = guid;
     409          13 :         ldb_request_add_control(
     410             :                 req,
     411             :                 DSDB_CONTROL_TRANSACTION_IDENTIFIER_OID,
     412             :                 false,
     413             :                 transaction_id);
     414          13 : }
     415             : 
     416             : /*
     417             :  * Test helper to add a session id and user SID
     418             :  */
     419          12 : static void add_session_data(
     420             :         TALLOC_CTX *ctx,
     421             :         struct ldb_context *ldb,
     422             :         const char *session,
     423             :         const char *user_sid)
     424             : {
     425          12 :         struct auth_session_info *sess = NULL;
     426          12 :         struct security_token *token = NULL;
     427          12 :         struct dom_sid *sid = NULL;
     428          12 :         struct GUID session_id;
     429          12 :         bool ok;
     430             : 
     431          12 :         sess = talloc_zero(ctx, struct auth_session_info);
     432          12 :         token = talloc_zero(ctx, struct security_token);
     433          12 :         sid = talloc_zero(ctx, struct dom_sid);
     434          12 :         ok = string_to_sid(sid, user_sid);
     435          12 :         assert_true(ok);
     436          12 :         token->sids = sid;
     437          12 :         sess->security_token = token;
     438          12 :         GUID_from_string(session, &session_id);
     439          12 :         sess->unique_session_token = session_id;
     440          12 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
     441          12 : }
     442             : 
     443           1 : static void test_get_transaction_id(void **state)
     444             : {
     445           1 :         struct ldb_request *req = NULL;
     446           1 :         struct GUID *guid;
     447           1 :         const char * const ID = "7130cb06-2062-6a1b-409e-3514c26b1773";
     448           1 :         char *guid_str = NULL;
     449           1 :         struct GUID_txt_buf guid_buff;
     450             : 
     451             : 
     452           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     453             : 
     454             : 
     455             :         /*
     456             :          * No transaction id, should return a zero guid
     457             :          */
     458           1 :         req = talloc_zero(ctx, struct ldb_request);
     459           1 :         guid = get_transaction_id(req);
     460           1 :         assert_null(guid);
     461           1 :         TALLOC_FREE(req);
     462             : 
     463             :         /*
     464             :          * And now test with the transaction_id set
     465             :          */
     466           1 :         req = talloc_zero(ctx, struct ldb_request);
     467           1 :         assert_non_null(req);
     468           1 :         add_transaction_id(req, ID);
     469             : 
     470           1 :         guid = get_transaction_id(req);
     471           1 :         guid_str = GUID_buf_string(guid, &guid_buff);
     472           1 :         assert_string_equal(ID, guid_str);
     473           1 :         TALLOC_FREE(req);
     474             : 
     475           1 :         TALLOC_FREE(ctx);
     476           1 : }
     477             : 
     478           1 : static void test_audit_group_hr(void **state)
     479             : {
     480           1 :         struct ldb_context *ldb = NULL;
     481           1 :         struct ldb_module  *module = NULL;
     482           1 :         struct ldb_request *req = NULL;
     483             : 
     484           1 :         struct tsocket_address *ts = NULL;
     485             : 
     486           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
     487           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     488             : 
     489           1 :         struct GUID transaction_id;
     490           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     491             : 
     492             : 
     493           1 :         char *line = NULL;
     494           1 :         const char *rs = NULL;
     495           1 :         regex_t regex;
     496           1 :         int ret;
     497             : 
     498             : 
     499           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     500             : 
     501           1 :         ldb = ldb_init(ctx, NULL);
     502             : 
     503           1 :         GUID_from_string(TRANSACTION, &transaction_id);
     504             : 
     505           1 :         module = talloc_zero(ctx, struct ldb_module);
     506           1 :         module->ldb = ldb;
     507             : 
     508           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
     509           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
     510             : 
     511           1 :         add_session_data(ctx, ldb, SESSION, SID);
     512             : 
     513           1 :         req = talloc_zero(ctx, struct ldb_request);
     514           1 :         req->operation =  LDB_ADD;
     515           1 :         add_transaction_id(req, TRANSACTION);
     516             : 
     517           1 :         line = audit_group_human_readable(
     518             :                 ctx,
     519             :                 module,
     520             :                 req,
     521             :                 "the-action",
     522             :                 "the-user-name",
     523             :                 "the-group-name",
     524             :                 LDB_ERR_OPERATIONS_ERROR);
     525           1 :         assert_non_null(line);
     526             : 
     527           1 :         rs =    "\\[the-action\\] at \\["
     528             :                 "[^]]*"
     529             :                 "\\] status \\[Operations error\\] "
     530             :                 "Remote host \\[ipv4:127.0.0.1:0\\] "
     531             :                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
     532             :                 "Group \\[the-group-name\\] "
     533             :                 "User \\[the-user-name\\]";
     534             : 
     535           1 :         ret = regcomp(&regex, rs, 0);
     536           1 :         assert_int_equal(0, ret);
     537             : 
     538           1 :         ret = regexec(&regex, line, 0, NULL, 0);
     539           1 :         assert_int_equal(0, ret);
     540             : 
     541           1 :         regfree(&regex);
     542           1 :         TALLOC_FREE(ctx);
     543             : 
     544           1 : }
     545             : 
     546             : /*
     547             :  * test get_parsed_dns
     548             :  * For this test we assume Valgrind or Address Sanitizer will detect any over
     549             :  * runs. Also we don't care that the values are DN's only that the value in the
     550             :  * element is copied to the parsed_dns.
     551             :  */
     552           1 : static void test_get_parsed_dns(void **state)
     553             : {
     554           1 :         struct ldb_message_element *el = NULL;
     555           1 :         struct parsed_dn *dns = NULL;
     556             : 
     557           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     558             : 
     559           1 :         el = talloc_zero(ctx, struct ldb_message_element);
     560             : 
     561             :         /*
     562             :          * empty element, zero dns
     563             :          */
     564           1 :         dns = get_parsed_dns(ctx, el);
     565           1 :         assert_null(dns);
     566             : 
     567             :         /*
     568             :          * one entry
     569             :          */
     570           1 :         el->num_values = 1;
     571           1 :         el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
     572           1 :         el->values[0] = data_blob_string_const("The first value");
     573             : 
     574           1 :         dns = get_parsed_dns(ctx, el);
     575             : 
     576           1 :         assert_ptr_equal(el->values[0].data, dns[0].v->data);
     577           1 :         assert_int_equal(el->values[0].length, dns[0].v->length);
     578             : 
     579           1 :         TALLOC_FREE(dns);
     580           1 :         TALLOC_FREE(el);
     581             : 
     582             : 
     583             :         /*
     584             :          * Multiple values
     585             :          */
     586           1 :         el = talloc_zero(ctx, struct ldb_message_element);
     587           1 :         el->num_values = 2;
     588           1 :         el->values = talloc_zero_array(ctx, DATA_BLOB, 2);
     589           1 :         el->values[0] = data_blob_string_const("The first value");
     590           1 :         el->values[0] = data_blob_string_const("The second value");
     591             : 
     592           1 :         dns = get_parsed_dns(ctx, el);
     593             : 
     594           1 :         assert_ptr_equal(el->values[0].data, dns[0].v->data);
     595           1 :         assert_int_equal(el->values[0].length, dns[0].v->length);
     596             : 
     597           1 :         assert_ptr_equal(el->values[1].data, dns[1].v->data);
     598           1 :         assert_int_equal(el->values[1].length, dns[1].v->length);
     599             : 
     600           1 :         TALLOC_FREE(ctx);
     601           1 : }
     602             : 
     603           1 : static void test_dn_compare(void **state)
     604             : {
     605             : 
     606           1 :         struct ldb_context *ldb = NULL;
     607           1 :         struct parsed_dn *a;
     608           1 :         DATA_BLOB ab;
     609             : 
     610           1 :         struct parsed_dn *b;
     611           1 :         DATA_BLOB bb;
     612             : 
     613           1 :         int res;
     614             : 
     615           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     616           1 :         const struct GUID *ZERO_GUID = talloc_zero(ctx, struct GUID);
     617             : 
     618           1 :         ldb = ldb_init(ctx, NULL);
     619           1 :         ldb_register_samba_handlers(ldb);
     620             : 
     621             : 
     622             :         /*
     623             :          * Identical binary DN's
     624             :          */
     625           1 :         ab = data_blob_string_const(
     626             :                 "<GUID=fbee08fd-6f75-4bd4-af3f-e4f063a6379e>;"
     627             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
     628           1 :         a = talloc_zero(ctx, struct parsed_dn);
     629           1 :         a->v = &ab;
     630             : 
     631           1 :         bb = data_blob_string_const(
     632             :                 "<GUID=fbee08fd-6f75-4bd4-af3f-e4f063a6379e>;"
     633             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
     634           1 :         b = talloc_zero(ctx, struct parsed_dn);
     635           1 :         b->v = &bb;
     636             : 
     637           1 :         res = dn_compare(ctx, ldb, a, b);
     638           1 :         assert_int_equal(BINARY_EQUAL, res);
     639             :         /*
     640             :          * DN's should not have been parsed
     641             :          */
     642           1 :         assert_null(a->dsdb_dn);
     643           1 :         assert_memory_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
     644           1 :         assert_null(b->dsdb_dn);
     645           1 :         assert_memory_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
     646             : 
     647           1 :         TALLOC_FREE(a);
     648           1 :         TALLOC_FREE(b);
     649             : 
     650             :         /*
     651             :          * differing binary DN's but equal GUID's
     652             :          */
     653           1 :         ab = data_blob_string_const(
     654             :                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651e>;"
     655             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=com");
     656           1 :         a = talloc_zero(ctx, struct parsed_dn);
     657           1 :         a->v = &ab;
     658             : 
     659           1 :         bb = data_blob_string_const(
     660             :                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651e>;"
     661             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
     662           1 :         b = talloc_zero(ctx, struct parsed_dn);
     663           1 :         b->v = &bb;
     664             : 
     665           1 :         res = dn_compare(ctx, ldb, a, b);
     666           1 :         assert_int_equal(EQUAL, res);
     667             :         /*
     668             :          * DN's should have been parsed
     669             :          */
     670           1 :         assert_non_null(a->dsdb_dn);
     671           1 :         assert_memory_not_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
     672           1 :         assert_non_null(b->dsdb_dn);
     673           1 :         assert_memory_not_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
     674             : 
     675           1 :         TALLOC_FREE(a);
     676           1 :         TALLOC_FREE(b);
     677             : 
     678             :         /*
     679             :          * differing binary DN's but and second guid greater
     680             :          */
     681           1 :         ab = data_blob_string_const(
     682             :                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651d>;"
     683             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=com");
     684           1 :         a = talloc_zero(ctx, struct parsed_dn);
     685           1 :         a->v = &ab;
     686             : 
     687           1 :         bb = data_blob_string_const(
     688             :                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651e>;"
     689             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
     690           1 :         b = talloc_zero(ctx, struct parsed_dn);
     691           1 :         b->v = &bb;
     692             : 
     693           1 :         res = dn_compare(ctx, ldb, a, b);
     694           1 :         assert_int_equal(LESS_THAN, res);
     695             :         /*
     696             :          * DN's should have been parsed
     697             :          */
     698           1 :         assert_non_null(a->dsdb_dn);
     699           1 :         assert_memory_not_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
     700           1 :         assert_non_null(b->dsdb_dn);
     701           1 :         assert_memory_not_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
     702             : 
     703           1 :         TALLOC_FREE(a);
     704           1 :         TALLOC_FREE(b);
     705             : 
     706             :         /*
     707             :          * differing binary DN's but and second guid less
     708             :          */
     709           1 :         ab = data_blob_string_const(
     710             :                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651d>;"
     711             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=com");
     712           1 :         a = talloc_zero(ctx, struct parsed_dn);
     713           1 :         a->v = &ab;
     714             : 
     715           1 :         bb = data_blob_string_const(
     716             :                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651c>;"
     717             :                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
     718           1 :         b = talloc_zero(ctx, struct parsed_dn);
     719           1 :         b->v = &bb;
     720             : 
     721           1 :         res = dn_compare(ctx, ldb, a, b);
     722           1 :         assert_int_equal(GREATER_THAN, res);
     723             :         /*
     724             :          * DN's should have been parsed
     725             :          */
     726           1 :         assert_non_null(a->dsdb_dn);
     727           1 :         assert_memory_not_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
     728           1 :         assert_non_null(b->dsdb_dn);
     729           1 :         assert_memory_not_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
     730             : 
     731           1 :         TALLOC_FREE(a);
     732           1 :         TALLOC_FREE(b);
     733             : 
     734           1 :         TALLOC_FREE(ctx);
     735           1 : }
     736             : 
     737           1 : static void test_get_primary_group_dn(void **state)
     738             : {
     739             : 
     740           1 :         struct ldb_context *ldb = NULL;
     741           1 :         struct ldb_module *module = NULL;
     742           1 :         const uint32_t RID = 71;
     743           1 :         struct dom_sid sid;
     744           1 :         const char *SID = "S-1-5-21-2470180966-3899876309-2637894779";
     745           1 :         const char *DN = "OU=Things,DC=ad,DC=testing,DC=samba,DC=org";
     746           1 :         const char *dn;
     747             : 
     748           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     749             : 
     750           1 :         ldb = ldb_init(ctx, NULL);
     751           1 :         ldb_register_samba_handlers(ldb);
     752             : 
     753           1 :         module = talloc_zero(ctx, struct ldb_module);
     754           1 :         module->ldb = ldb;
     755             : 
     756             :         /*
     757             :          * Pass an empty dom sid this will cause dom_sid_split_rid to fail;
     758             :          * assign to sid.num_auths to suppress a valgrind warning.
     759             :          */
     760           1 :         sid.num_auths = 0;
     761           1 :         dn = get_primary_group_dn(ctx, module, &sid, RID);
     762           1 :         assert_null(dn);
     763             : 
     764             :         /*
     765             :          * A valid dom sid
     766             :          */
     767           1 :         assert_true(string_to_sid(&sid, SID));
     768           1 :         g_dn = DN;
     769           1 :         dn = get_primary_group_dn(ctx, module, &sid, RID);
     770           1 :         assert_non_null(dn);
     771           1 :         assert_string_equal(DN, dn);
     772           1 :         assert_int_equal(LDB_SCOPE_BASE, g_scope);
     773           1 :         assert_int_equal(0, g_dsdb_flags);
     774           1 :         assert_null(g_attrs);
     775           1 :         assert_null(g_exp_fmt);
     776           1 :         assert_string_equal
     777             :                 ("<SID=S-1-5-21-2470180966-3899876309-71>",
     778             :                 ldb_dn_get_extended_linearized(ctx, g_basedn, 1));
     779             : 
     780             :         /*
     781             :          * Test dsdb search failure
     782             :          */
     783           1 :         g_status = LDB_ERR_NO_SUCH_OBJECT;
     784           1 :         dn = get_primary_group_dn(ctx, module, &sid, RID);
     785           1 :         assert_null(dn);
     786             : 
     787           1 :         TALLOC_FREE(ldb);
     788           1 :         TALLOC_FREE(ctx);
     789           1 : }
     790             : 
     791           1 : static void test_audit_group_json(void **state)
     792             : {
     793           1 :         struct ldb_context *ldb = NULL;
     794           1 :         struct ldb_module  *module = NULL;
     795           1 :         struct ldb_request *req = NULL;
     796             : 
     797           1 :         struct tsocket_address *ts = NULL;
     798             : 
     799           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
     800           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     801             : 
     802           1 :         struct GUID transaction_id;
     803           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     804             : 
     805           1 :         enum event_id_type event_id = EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP;
     806             : 
     807           1 :         struct json_object json;
     808           1 :         json_t *audit = NULL;
     809           1 :         json_t *v = NULL;
     810           1 :         json_t *o = NULL;
     811           1 :         time_t before;
     812           1 :         struct timeval tv;
     813           1 :         int rc;
     814             : 
     815             : 
     816           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     817             : 
     818           1 :         ldb = ldb_init(ctx, NULL);
     819             : 
     820           1 :         GUID_from_string(TRANSACTION, &transaction_id);
     821             : 
     822           1 :         module = talloc_zero(ctx, struct ldb_module);
     823           1 :         module->ldb = ldb;
     824             : 
     825           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
     826           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
     827             : 
     828           1 :         add_session_data(ctx, ldb, SESSION, SID);
     829             : 
     830           1 :         req = talloc_zero(ctx, struct ldb_request);
     831           1 :         req->operation =  LDB_ADD;
     832           1 :         add_transaction_id(req, TRANSACTION);
     833             : 
     834           1 :         rc = gettimeofday(&tv, NULL);
     835           1 :         assert_return_code(rc, errno);
     836           1 :         before = tv.tv_sec;
     837           1 :         json = audit_group_json(module,
     838             :                                 req,
     839             :                                 "the-action",
     840             :                                 "the-user-name",
     841             :                                 "the-group-name",
     842             :                                 event_id,
     843             :                                 LDB_SUCCESS);
     844           1 :         assert_int_equal(3, json_object_size(json.root));
     845             : 
     846           1 :         v = json_object_get(json.root, "type");
     847           1 :         assert_non_null(v);
     848           1 :         assert_string_equal("groupChange", json_string_value(v));
     849             : 
     850           1 :         v = json_object_get(json.root, "timestamp");
     851           1 :         assert_non_null(v);
     852           1 :         assert_true(json_is_string(v));
     853           1 :         check_timestamp(before, json_string_value(v));
     854             : 
     855           1 :         audit = json_object_get(json.root, "groupChange");
     856           1 :         assert_non_null(audit);
     857           1 :         assert_true(json_is_object(audit));
     858           1 :         assert_int_equal(11, json_object_size(audit));
     859             : 
     860           1 :         o = json_object_get(audit, "version");
     861           1 :         assert_non_null(o);
     862           1 :         check_version(o, AUDIT_MAJOR, AUDIT_MINOR);
     863             : 
     864           1 :         v = json_object_get(audit, "eventId");
     865           1 :         assert_non_null(v);
     866           1 :         assert_true(json_is_integer(v));
     867           1 :         assert_int_equal(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP,
     868             :                          json_integer_value(v));
     869             : 
     870           1 :         v = json_object_get(audit, "statusCode");
     871           1 :         assert_non_null(v);
     872           1 :         assert_true(json_is_integer(v));
     873           1 :         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
     874             : 
     875           1 :         v = json_object_get(audit, "status");
     876           1 :         assert_non_null(v);
     877           1 :         assert_true(json_is_string(v));
     878           1 :         assert_string_equal("Success", json_string_value(v));
     879             : 
     880           1 :         v = json_object_get(audit, "user");
     881           1 :         assert_non_null(v);
     882           1 :         assert_true(json_is_string(v));
     883           1 :         assert_string_equal("the-user-name", json_string_value(v));
     884             : 
     885           1 :         v = json_object_get(audit, "group");
     886           1 :         assert_non_null(v);
     887           1 :         assert_true(json_is_string(v));
     888           1 :         assert_string_equal("the-group-name", json_string_value(v));
     889             : 
     890           1 :         v = json_object_get(audit, "action");
     891           1 :         assert_non_null(v);
     892           1 :         assert_true(json_is_string(v));
     893           1 :         assert_string_equal("the-action", json_string_value(v));
     894             : 
     895           1 :         json_free(&json);
     896           1 :         TALLOC_FREE(ctx);
     897           1 : }
     898             : 
     899           1 : static void test_audit_group_json_error(void **state)
     900             : {
     901           1 :         struct ldb_context *ldb = NULL;
     902           1 :         struct ldb_module  *module = NULL;
     903           1 :         struct ldb_request *req = NULL;
     904             : 
     905           1 :         struct tsocket_address *ts = NULL;
     906             : 
     907           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
     908           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     909             : 
     910           1 :         struct GUID transaction_id;
     911           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
     912             : 
     913           1 :         enum event_id_type event_id = EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP;
     914             : 
     915           1 :         struct json_object json;
     916           1 :         json_t *audit = NULL;
     917           1 :         json_t *v = NULL;
     918           1 :         json_t *o = NULL;
     919           1 :         time_t before;
     920           1 :         struct timeval tv;
     921           1 :         int rc;
     922             : 
     923             : 
     924           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
     925             : 
     926           1 :         ldb = ldb_init(ctx, NULL);
     927             : 
     928           1 :         GUID_from_string(TRANSACTION, &transaction_id);
     929             : 
     930           1 :         module = talloc_zero(ctx, struct ldb_module);
     931           1 :         module->ldb = ldb;
     932             : 
     933           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
     934           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
     935             : 
     936           1 :         add_session_data(ctx, ldb, SESSION, SID);
     937             : 
     938           1 :         req = talloc_zero(ctx, struct ldb_request);
     939           1 :         req->operation =  LDB_ADD;
     940           1 :         add_transaction_id(req, TRANSACTION);
     941             : 
     942           1 :         rc = gettimeofday(&tv, NULL);
     943           1 :         assert_return_code(rc, errno);
     944           1 :         before = tv.tv_sec;
     945           1 :         json = audit_group_json(module,
     946             :                                 req,
     947             :                                 "the-action",
     948             :                                 "the-user-name",
     949             :                                 "the-group-name",
     950             :                                 event_id,
     951             :                                 LDB_ERR_OPERATIONS_ERROR);
     952           1 :         assert_int_equal(3, json_object_size(json.root));
     953             : 
     954           1 :         v = json_object_get(json.root, "type");
     955           1 :         assert_non_null(v);
     956           1 :         assert_string_equal("groupChange", json_string_value(v));
     957             : 
     958           1 :         v = json_object_get(json.root, "timestamp");
     959           1 :         assert_non_null(v);
     960           1 :         assert_true(json_is_string(v));
     961           1 :         check_timestamp(before, json_string_value(v));
     962             : 
     963           1 :         audit = json_object_get(json.root, "groupChange");
     964           1 :         assert_non_null(audit);
     965           1 :         assert_true(json_is_object(audit));
     966           1 :         assert_int_equal(11, json_object_size(audit));
     967             : 
     968           1 :         o = json_object_get(audit, "version");
     969           1 :         assert_non_null(o);
     970           1 :         check_version(o, AUDIT_MAJOR, AUDIT_MINOR);
     971             : 
     972           1 :         v = json_object_get(audit, "eventId");
     973           1 :         assert_non_null(v);
     974           1 :         assert_true(json_is_integer(v));
     975           1 :         assert_int_equal(
     976             :                 EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP,
     977             :                 json_integer_value(v));
     978             : 
     979           1 :         v = json_object_get(audit, "statusCode");
     980           1 :         assert_non_null(v);
     981           1 :         assert_true(json_is_integer(v));
     982           1 :         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
     983             : 
     984           1 :         v = json_object_get(audit, "status");
     985           1 :         assert_non_null(v);
     986           1 :         assert_true(json_is_string(v));
     987           1 :         assert_string_equal("Operations error", json_string_value(v));
     988             : 
     989           1 :         v = json_object_get(audit, "user");
     990           1 :         assert_non_null(v);
     991           1 :         assert_true(json_is_string(v));
     992           1 :         assert_string_equal("the-user-name", json_string_value(v));
     993             : 
     994           1 :         v = json_object_get(audit, "group");
     995           1 :         assert_non_null(v);
     996           1 :         assert_true(json_is_string(v));
     997           1 :         assert_string_equal("the-group-name", json_string_value(v));
     998             : 
     999           1 :         v = json_object_get(audit, "action");
    1000           1 :         assert_non_null(v);
    1001           1 :         assert_true(json_is_string(v));
    1002           1 :         assert_string_equal("the-action", json_string_value(v));
    1003             : 
    1004           1 :         json_free(&json);
    1005           1 :         TALLOC_FREE(ctx);
    1006           1 : }
    1007             : 
    1008           1 : static void test_audit_group_json_no_event(void **state)
    1009             : {
    1010           1 :         struct ldb_context *ldb = NULL;
    1011           1 :         struct ldb_module  *module = NULL;
    1012           1 :         struct ldb_request *req = NULL;
    1013             : 
    1014           1 :         struct tsocket_address *ts = NULL;
    1015             : 
    1016           1 :         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1017           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1018             : 
    1019           1 :         struct GUID transaction_id;
    1020           1 :         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1021             : 
    1022           1 :         enum event_id_type event_id = EVT_ID_NONE;
    1023             : 
    1024           1 :         struct json_object json;
    1025           1 :         json_t *audit = NULL;
    1026           1 :         json_t *v = NULL;
    1027           1 :         json_t *o = NULL;
    1028           1 :         time_t before;
    1029           1 :         struct timeval tv;
    1030           1 :         int rc;
    1031             : 
    1032             : 
    1033           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1034             : 
    1035           1 :         ldb = ldb_init(ctx, NULL);
    1036             : 
    1037           1 :         GUID_from_string(TRANSACTION, &transaction_id);
    1038             : 
    1039           1 :         module = talloc_zero(ctx, struct ldb_module);
    1040           1 :         module->ldb = ldb;
    1041             : 
    1042           1 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
    1043           1 :         ldb_set_opaque(ldb, "remoteAddress", ts);
    1044             : 
    1045           1 :         add_session_data(ctx, ldb, SESSION, SID);
    1046             : 
    1047           1 :         req = talloc_zero(ctx, struct ldb_request);
    1048           1 :         req->operation =  LDB_ADD;
    1049           1 :         add_transaction_id(req, TRANSACTION);
    1050             : 
    1051           1 :         rc = gettimeofday(&tv, NULL);
    1052           1 :         assert_return_code(rc, errno);
    1053           1 :         before = tv.tv_sec;
    1054           1 :         json = audit_group_json(module,
    1055             :                                 req,
    1056             :                                 "the-action",
    1057             :                                 "the-user-name",
    1058             :                                 "the-group-name",
    1059             :                                 event_id,
    1060             :                                 LDB_SUCCESS);
    1061           1 :         assert_int_equal(3, json_object_size(json.root));
    1062             : 
    1063           1 :         v = json_object_get(json.root, "type");
    1064           1 :         assert_non_null(v);
    1065           1 :         assert_string_equal("groupChange", json_string_value(v));
    1066             : 
    1067           1 :         v = json_object_get(json.root, "timestamp");
    1068           1 :         assert_non_null(v);
    1069           1 :         assert_true(json_is_string(v));
    1070           1 :         check_timestamp(before, json_string_value(v));
    1071             : 
    1072           1 :         audit = json_object_get(json.root, "groupChange");
    1073           1 :         assert_non_null(audit);
    1074           1 :         assert_true(json_is_object(audit));
    1075           1 :         assert_int_equal(10, json_object_size(audit));
    1076             : 
    1077           1 :         o = json_object_get(audit, "version");
    1078           1 :         assert_non_null(o);
    1079           1 :         check_version(o, AUDIT_MAJOR, AUDIT_MINOR);
    1080             : 
    1081           1 :         v = json_object_get(audit, "eventId");
    1082           1 :         assert_null(v);
    1083             : 
    1084           1 :         v = json_object_get(audit, "statusCode");
    1085           1 :         assert_non_null(v);
    1086           1 :         assert_true(json_is_integer(v));
    1087           1 :         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
    1088             : 
    1089           1 :         v = json_object_get(audit, "status");
    1090           1 :         assert_non_null(v);
    1091           1 :         assert_true(json_is_string(v));
    1092           1 :         assert_string_equal("Success", json_string_value(v));
    1093             : 
    1094           1 :         v = json_object_get(audit, "user");
    1095           1 :         assert_non_null(v);
    1096           1 :         assert_true(json_is_string(v));
    1097           1 :         assert_string_equal("the-user-name", json_string_value(v));
    1098             : 
    1099           1 :         v = json_object_get(audit, "group");
    1100           1 :         assert_non_null(v);
    1101           1 :         assert_true(json_is_string(v));
    1102           1 :         assert_string_equal("the-group-name", json_string_value(v));
    1103             : 
    1104           1 :         v = json_object_get(audit, "action");
    1105           1 :         assert_non_null(v);
    1106           1 :         assert_true(json_is_string(v));
    1107           1 :         assert_string_equal("the-action", json_string_value(v));
    1108             : 
    1109           1 :         json_free(&json);
    1110           1 :         TALLOC_FREE(ctx);
    1111           1 : }
    1112           8 : static void setup_ldb(
    1113             :         TALLOC_CTX *ctx,
    1114             :         struct ldb_context **ldb,
    1115             :         struct ldb_module **module,
    1116             :         const char *ip,
    1117             :         const char *session,
    1118             :         const char *sid)
    1119             : {
    1120           8 :         struct tsocket_address *ts = NULL;
    1121           8 :         struct audit_context *context = NULL;
    1122             : 
    1123           8 :         *ldb = ldb_init(ctx, NULL);
    1124           8 :         ldb_register_samba_handlers(*ldb);
    1125             : 
    1126             : 
    1127           8 :         *module = talloc_zero(ctx, struct ldb_module);
    1128           8 :         (*module)->ldb = *ldb;
    1129             : 
    1130           8 :         context = talloc_zero(*module, struct audit_context);
    1131           8 :         context->send_events = true;
    1132           8 :         context->msg_ctx = (struct imessaging_context *) 0x01;
    1133             : 
    1134           8 :         ldb_module_set_private(*module, context);
    1135             : 
    1136           8 :         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
    1137           8 :         ldb_set_opaque(*ldb, "remoteAddress", ts);
    1138             : 
    1139           8 :         add_session_data(ctx, *ldb, session, sid);
    1140           8 : }
    1141             : 
    1142             : /*
    1143             :  * Test the removal of a user from a group.
    1144             :  *
    1145             :  * The new element contains one group member
    1146             :  * The old element contains two group member
    1147             :  *
    1148             :  * Expect to see the removed entry logged.
    1149             :  *
    1150             :  * This test confirms bug 13664
    1151             :  * https://bugzilla.samba.org/show_bug.cgi?id=13664
    1152             :  */
    1153           1 : static void test_log_membership_changes_removed(void **state)
    1154             : {
    1155           1 :         struct ldb_context *ldb = NULL;
    1156           1 :         struct ldb_module  *module = NULL;
    1157           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1158           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1159           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1160           1 :         const char * const IP = "127.0.0.1";
    1161           1 :         struct ldb_request *req = NULL;
    1162           1 :         struct ldb_message_element *new_el = NULL;
    1163           1 :         struct ldb_message_element *old_el = NULL;
    1164           1 :         uint32_t group_type = GTYPE_SECURITY_GLOBAL_GROUP;
    1165           1 :         int status = 0;
    1166           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1167             : 
    1168           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1169             : 
    1170             :         /*
    1171             :          * Build the ldb_request
    1172             :          */
    1173           1 :         req = talloc_zero(ctx, struct ldb_request);
    1174           1 :         req->operation =  LDB_ADD;
    1175           1 :         add_transaction_id(req, TRANSACTION);
    1176             : 
    1177             :         /*
    1178             :          * Populate the new elements, containing one entry.
    1179             :          * Indicating that one element has been removed
    1180             :          */
    1181           1 :         new_el = talloc_zero(ctx, struct ldb_message_element);
    1182           1 :         new_el->num_values = 1;
    1183           1 :         new_el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1184           1 :         new_el->values[0] = data_blob_string_const(
    1185             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1186             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1187             :                 "DC=example,DC=com");
    1188             : 
    1189             :         /*
    1190             :          * Populate the old elements, with two elements
    1191             :          * The first is the same as the one in new elements.
    1192             :          */
    1193           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1194           1 :         old_el->num_values = 2;
    1195           1 :         old_el->values = talloc_zero_array(ctx, DATA_BLOB, 2);
    1196           1 :         old_el->values[0] = data_blob_string_const(
    1197             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1198             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1199             :                 "DC=samba,DC=example,DC=com");
    1200           1 :         old_el->values[1] = data_blob_string_const(
    1201             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1202             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1203             :                 "DC=example,DC=com");
    1204             : 
    1205             :         /*
    1206             :          * call log_membership_changes
    1207             :          */
    1208           1 :         messages_sent = 0;
    1209           1 :         log_membership_changes(module, req, new_el, old_el, group_type, status);
    1210             : 
    1211             :         /*
    1212             :          * Check the results
    1213             :          */
    1214           1 :         assert_int_equal(1, messages_sent);
    1215             : 
    1216           1 :         check_group_change_message(
    1217             :             0,
    1218             :             "cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
    1219             :             "Removed",
    1220           1 :             EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP);
    1221             : 
    1222             :         /*
    1223             :          * Clean up
    1224             :          */
    1225           1 :         json_free(&messages[0]);
    1226           1 :         TALLOC_FREE(ctx);
    1227           1 : }
    1228             : 
    1229             : /* test log_membership_changes
    1230             :  *
    1231             :  * old contains 2 user dn's
    1232             :  * new contains 0 user dn's
    1233             :  *
    1234             :  * Expect to see both dn's logged as deleted.
    1235             :  */
    1236           1 : static void test_log_membership_changes_remove_all(void **state)
    1237             : {
    1238           1 :         struct ldb_context *ldb = NULL;
    1239           1 :         struct ldb_module  *module = NULL;
    1240           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1241           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1242           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1243           1 :         const char * const IP = "127.0.0.1";
    1244           1 :         struct ldb_request *req = NULL;
    1245           1 :         struct ldb_message_element *new_el = NULL;
    1246           1 :         struct ldb_message_element *old_el = NULL;
    1247           1 :         int status = 0;
    1248           1 :         uint32_t group_type = GTYPE_SECURITY_BUILTIN_LOCAL_GROUP;
    1249           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1250             : 
    1251           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1252             : 
    1253             :         /*
    1254             :          * Build the ldb_request
    1255             :          */
    1256           1 :         req = talloc_zero(ctx, struct ldb_request);
    1257           1 :         req->operation =  LDB_ADD;
    1258           1 :         add_transaction_id(req, TRANSACTION);
    1259             : 
    1260             :         /*
    1261             :          * Populate the new elements, containing no entries.
    1262             :          * Indicating that all elements have been removed
    1263             :          */
    1264           1 :         new_el = talloc_zero(ctx, struct ldb_message_element);
    1265           1 :         new_el->num_values = 0;
    1266           1 :         new_el->values = NULL;
    1267             : 
    1268             :         /*
    1269             :          * Populate the old elements, with two elements
    1270             :          */
    1271           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1272           1 :         old_el->num_values = 2;
    1273           1 :         old_el->values = talloc_zero_array(ctx, DATA_BLOB, 2);
    1274           1 :         old_el->values[0] = data_blob_string_const(
    1275             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1276             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1277             :                 "DC=samba,DC=example,DC=com");
    1278           1 :         old_el->values[1] = data_blob_string_const(
    1279             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1280             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1281             :                 "DC=example,DC=com");
    1282             : 
    1283             :         /*
    1284             :          * call log_membership_changes
    1285             :          */
    1286           1 :         messages_sent = 0;
    1287           1 :         log_membership_changes(module, req, new_el, old_el, group_type, status);
    1288             : 
    1289             :         /*
    1290             :          * Check the results
    1291             :          */
    1292           1 :         assert_int_equal(2, messages_sent);
    1293             : 
    1294           1 :         check_group_change_message(
    1295             :             0,
    1296             :             "cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
    1297             :             "Removed",
    1298           1 :             EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP);
    1299             : 
    1300           1 :         check_group_change_message(
    1301             :             1,
    1302             :             "CN=testuser131953,CN=Users,DC=addom,DC=samba,DC=example,DC=com",
    1303             :             "Removed",
    1304           1 :             EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP);
    1305             : 
    1306             :         /*
    1307             :          * Clean up
    1308             :          */
    1309           1 :         json_free(&messages[0]);
    1310           1 :         json_free(&messages[1]);
    1311           1 :         TALLOC_FREE(ctx);
    1312           1 : }
    1313             : 
    1314             : /* test log_membership_changes
    1315             :  *
    1316             :  * Add an entry.
    1317             :  *
    1318             :  * Old entries contains a single user dn
    1319             :  * New entries contains 2 user dn's, one matching the dn in old entries
    1320             :  *
    1321             :  * Should see a single new entry logged.
    1322             :  */
    1323           1 : static void test_log_membership_changes_added(void **state)
    1324             : {
    1325           1 :         struct ldb_context *ldb = NULL;
    1326           1 :         struct ldb_module  *module = NULL;
    1327           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1328           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1329           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1330           1 :         const char * const IP = "127.0.0.1";
    1331           1 :         struct ldb_request *req = NULL;
    1332           1 :         struct ldb_message_element *new_el = NULL;
    1333           1 :         struct ldb_message_element *old_el = NULL;
    1334           1 :         uint32_t group_type = GTYPE_SECURITY_DOMAIN_LOCAL_GROUP;
    1335           1 :         int status = 0;
    1336           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1337             : 
    1338           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1339             : 
    1340             :         /*
    1341             :          * Build the ldb_request
    1342             :          */
    1343           1 :         req = talloc_zero(ctx, struct ldb_request);
    1344           1 :         req->operation =  LDB_ADD;
    1345           1 :         add_transaction_id(req, TRANSACTION);
    1346             : 
    1347             :         /*
    1348             :          * Populate the old elements adding a single entry.
    1349             :          */
    1350           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1351           1 :         old_el->num_values = 1;
    1352           1 :         old_el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1353           1 :         old_el->values[0] = data_blob_string_const(
    1354             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1355             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1356             :                 "DC=example,DC=com");
    1357             : 
    1358             :         /*
    1359             :          * Populate the new elements adding two entries. One matches the entry
    1360             :          * in old elements. We expect to see the other element logged as Added
    1361             :          */
    1362           1 :         new_el = talloc_zero(ctx, struct ldb_message_element);
    1363           1 :         new_el->num_values = 2;
    1364           1 :         new_el->values = talloc_zero_array(ctx, DATA_BLOB, 2);
    1365           1 :         new_el->values[0] = data_blob_string_const(
    1366             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1367             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1368             :                 "DC=samba,DC=example,DC=com");
    1369           1 :         new_el->values[1] = data_blob_string_const(
    1370             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1371             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1372             :                 "DC=example,DC=com");
    1373             : 
    1374             :         /*
    1375             :          * call log_membership_changes
    1376             :          */
    1377           1 :         messages_sent = 0;
    1378           1 :         log_membership_changes(module, req, new_el, old_el, group_type, status);
    1379             : 
    1380             :         /*
    1381             :          * Check the results
    1382             :          */
    1383           1 :         assert_int_equal(1, messages_sent);
    1384             : 
    1385           1 :         check_group_change_message(
    1386             :             0,
    1387             :             "cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
    1388             :             "Added",
    1389           1 :             EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP);
    1390             : 
    1391             :         /*
    1392             :          * Clean up
    1393             :          */
    1394           1 :         json_free(&messages[0]);
    1395           1 :         TALLOC_FREE(ctx);
    1396           1 : }
    1397             : 
    1398             : /*
    1399             :  * test log_membership_changes.
    1400             :  *
    1401             :  * Old entries is empty
    1402             :  * New entries contains 2 user dn's
    1403             :  *
    1404             :  * Expect to see log messages for two added users
    1405             :  */
    1406           1 : static void test_log_membership_changes_add_to_empty(void **state)
    1407             : {
    1408           1 :         struct ldb_context *ldb = NULL;
    1409           1 :         struct ldb_module  *module = NULL;
    1410           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1411           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1412           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1413           1 :         const char * const IP = "127.0.0.1";
    1414           1 :         struct ldb_request *req = NULL;
    1415           1 :         struct ldb_message_element *new_el = NULL;
    1416           1 :         struct ldb_message_element *old_el = NULL;
    1417           1 :         uint32_t group_type = GTYPE_SECURITY_UNIVERSAL_GROUP;
    1418           1 :         int status = 0;
    1419           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1420             : 
    1421             :         /*
    1422             :          * Set up the ldb and module structures
    1423             :          */
    1424           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1425             : 
    1426             :         /*
    1427             :          * Build the request structure
    1428             :          */
    1429           1 :         req = talloc_zero(ctx, struct ldb_request);
    1430           1 :         req->operation =  LDB_ADD;
    1431           1 :         add_transaction_id(req, TRANSACTION);
    1432             : 
    1433             :         /*
    1434             :          * Build the element containing the old values
    1435             :          */
    1436           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1437           1 :         old_el->num_values = 0;
    1438           1 :         old_el->values = NULL;
    1439             : 
    1440             :         /*
    1441             :          * Build the element containing the new values
    1442             :          */
    1443           1 :         new_el = talloc_zero(ctx, struct ldb_message_element);
    1444           1 :         new_el->num_values = 2;
    1445           1 :         new_el->values = talloc_zero_array(ctx, DATA_BLOB, 2);
    1446           1 :         new_el->values[0] = data_blob_string_const(
    1447             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1448             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1449             :                 "DC=samba,DC=example,DC=com");
    1450           1 :         new_el->values[1] = data_blob_string_const(
    1451             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1452             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1453             :                 "DC=example,DC=com");
    1454             : 
    1455             :         /*
    1456             :          * Run log membership changes
    1457             :          */
    1458           1 :         messages_sent = 0;
    1459           1 :         log_membership_changes(module, req, new_el, old_el, group_type, status);
    1460           1 :         assert_int_equal(2, messages_sent);
    1461             : 
    1462           1 :         check_group_change_message(
    1463             :             0,
    1464             :             "cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
    1465             :             "Added",
    1466           1 :             EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP);
    1467             : 
    1468           1 :         check_group_change_message(
    1469             :             1,
    1470             :             "CN=testuser131953,CN=Users,DC=addom,DC=samba,DC=example,DC=com",
    1471             :             "Added",
    1472           1 :             EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP);
    1473             : 
    1474           1 :         json_free(&messages[0]);
    1475           1 :         json_free(&messages[1]);
    1476           1 :         TALLOC_FREE(ctx);
    1477           1 : }
    1478             : 
    1479             : /* test log_membership_changes
    1480             :  *
    1481             :  * Test Replication Meta Data flag handling.
    1482             :  *
    1483             :  * 4 entries in old and new entries with their RMD_FLAGS set as below:
    1484             :  *    old   new
    1485             :  * 1)  0     0    Not logged
    1486             :  * 2)  1     1    Both deleted, no change not logged
    1487             :  * 3)  0     1    New tagged as deleted, log as deleted
    1488             :  * 4)  1     0    Has been undeleted, log as an add
    1489             :  *
    1490             :  * Should see a single new entry logged.
    1491             :  */
    1492           1 : static void test_log_membership_changes_rmd_flags(void **state)
    1493             : {
    1494           1 :         struct ldb_context *ldb = NULL;
    1495           1 :         struct ldb_module  *module = NULL;
    1496           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1497           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1498           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1499           1 :         const char * const IP = "127.0.0.1";
    1500           1 :         struct ldb_request *req = NULL;
    1501           1 :         struct ldb_message_element *new_el = NULL;
    1502           1 :         struct ldb_message_element *old_el = NULL;
    1503           1 :         uint32_t group_type = GTYPE_SECURITY_GLOBAL_GROUP;
    1504           1 :         int status = 0;
    1505           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1506             : 
    1507           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1508             : 
    1509             :         /*
    1510             :          * Build the ldb_request
    1511             :          */
    1512           1 :         req = talloc_zero(ctx, struct ldb_request);
    1513           1 :         req->operation =  LDB_ADD;
    1514           1 :         add_transaction_id(req, TRANSACTION);
    1515             : 
    1516             :         /*
    1517             :          * Populate the old elements.
    1518             :          */
    1519           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1520           1 :         old_el->num_values = 4;
    1521           1 :         old_el->values = talloc_zero_array(ctx, DATA_BLOB, 4);
    1522           1 :         old_el->values[0] = data_blob_string_const(
    1523             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1524             :                 "<RMD_FLAGS=0>;"
    1525             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1526             :                 "DC=samba,DC=example,DC=com");
    1527           1 :         old_el->values[1] = data_blob_string_const(
    1528             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681c>;"
    1529             :                 "<RMD_FLAGS=1>;"
    1530             :                 "cn=grpadttstuser02,cn=users,DC=addom,"
    1531             :                 "DC=samba,DC=example,DC=com");
    1532           1 :         old_el->values[2] = data_blob_string_const(
    1533             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681d>;"
    1534             :                 "<RMD_FLAGS=0>;"
    1535             :                 "cn=grpadttstuser03,cn=users,DC=addom,"
    1536             :                 "DC=samba,DC=example,DC=com");
    1537           1 :         old_el->values[3] = data_blob_string_const(
    1538             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681e>;"
    1539             :                 "<RMD_FLAGS=1>;"
    1540             :                 "cn=grpadttstuser04,cn=users,DC=addom,"
    1541             :                 "DC=samba,DC=example,DC=com");
    1542             : 
    1543             :         /*
    1544             :          * Populate the new elements.
    1545             :          */
    1546           1 :         new_el = talloc_zero(ctx, struct ldb_message_element);
    1547           1 :         new_el->num_values = 4;
    1548           1 :         new_el->values = talloc_zero_array(ctx, DATA_BLOB, 4);
    1549           1 :         new_el->values[0] = data_blob_string_const(
    1550             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1551             :                 "<RMD_FLAGS=0>;"
    1552             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1553             :                 "DC=samba,DC=example,DC=com");
    1554           1 :         new_el->values[1] = data_blob_string_const(
    1555             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681c>;"
    1556             :                 "<RMD_FLAGS=1>;"
    1557             :                 "cn=grpadttstuser02,cn=users,DC=addom,"
    1558             :                 "DC=samba,DC=example,DC=com");
    1559           1 :         new_el->values[2] = data_blob_string_const(
    1560             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681d>;"
    1561             :                 "<RMD_FLAGS=1>;"
    1562             :                 "cn=grpadttstuser03,cn=users,DC=addom,"
    1563             :                 "DC=samba,DC=example,DC=com");
    1564           1 :         new_el->values[3] = data_blob_string_const(
    1565             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681e>;"
    1566             :                 "<RMD_FLAGS=0>;"
    1567             :                 "cn=grpadttstuser04,cn=users,DC=addom,"
    1568             :                 "DC=samba,DC=example,DC=com");
    1569             : 
    1570             :         /*
    1571             :          * call log_membership_changes
    1572             :          */
    1573           1 :         messages_sent = 0;
    1574           1 :         log_membership_changes(module, req, new_el, old_el, group_type, status);
    1575             : 
    1576             :         /*
    1577             :          * Check the results
    1578             :          */
    1579           1 :         assert_int_equal(2, messages_sent);
    1580             : 
    1581           1 :         check_group_change_message(
    1582             :             0,
    1583             :             "cn=grpadttstuser03,cn=users,DC=addom,DC=samba,DC=example,DC=com",
    1584             :             "Removed",
    1585           1 :             EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP);
    1586           1 :         check_group_change_message(
    1587             :             1,
    1588             :             "cn=grpadttstuser04,cn=users,DC=addom,DC=samba,DC=example,DC=com",
    1589             :             "Added",
    1590           1 :             EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP);
    1591             : 
    1592             :         /*
    1593             :          * Clean up
    1594             :          */
    1595           1 :         json_free(&messages[0]);
    1596           1 :         json_free(&messages[1]);
    1597           1 :         TALLOC_FREE(ctx);
    1598           1 : }
    1599             : 
    1600           1 : static void test_get_add_member_event(void **state)
    1601             : {
    1602           1 :         assert_int_equal(
    1603             :             EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP,
    1604             :             get_add_member_event(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP));
    1605             : 
    1606           1 :         assert_int_equal(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP,
    1607             :                          get_add_member_event(GTYPE_SECURITY_GLOBAL_GROUP));
    1608             : 
    1609           1 :         assert_int_equal(
    1610             :             EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP,
    1611             :             get_add_member_event(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
    1612             : 
    1613           1 :         assert_int_equal(EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP,
    1614             :                          get_add_member_event(GTYPE_SECURITY_UNIVERSAL_GROUP));
    1615             : 
    1616           1 :         assert_int_equal(EVT_ID_USER_ADDED_TO_GLOBAL_GROUP,
    1617             :                          get_add_member_event(GTYPE_DISTRIBUTION_GLOBAL_GROUP));
    1618             : 
    1619           1 :         assert_int_equal(
    1620             :             EVT_ID_USER_ADDED_TO_LOCAL_GROUP,
    1621             :             get_add_member_event(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP));
    1622             : 
    1623           1 :         assert_int_equal(
    1624             :             EVT_ID_USER_ADDED_TO_UNIVERSAL_GROUP,
    1625             :             get_add_member_event(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP));
    1626             : 
    1627           1 :         assert_int_equal(EVT_ID_NONE, get_add_member_event(0));
    1628             : 
    1629           1 :         assert_int_equal(EVT_ID_NONE, get_add_member_event(UINT32_MAX));
    1630           1 : }
    1631             : 
    1632           1 : static void test_get_remove_member_event(void **state)
    1633             : {
    1634           1 :         assert_int_equal(
    1635             :             EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP,
    1636             :             get_remove_member_event(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP));
    1637             : 
    1638           1 :         assert_int_equal(EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP,
    1639             :                          get_remove_member_event(GTYPE_SECURITY_GLOBAL_GROUP));
    1640             : 
    1641           1 :         assert_int_equal(
    1642             :             EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP,
    1643             :             get_remove_member_event(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
    1644             : 
    1645           1 :         assert_int_equal(
    1646             :             EVT_ID_USER_REMOVED_FROM_UNIVERSAL_SEC_GROUP,
    1647             :             get_remove_member_event(GTYPE_SECURITY_UNIVERSAL_GROUP));
    1648             : 
    1649           1 :         assert_int_equal(
    1650             :             EVT_ID_USER_REMOVED_FROM_GLOBAL_GROUP,
    1651             :             get_remove_member_event(GTYPE_DISTRIBUTION_GLOBAL_GROUP));
    1652             : 
    1653           1 :         assert_int_equal(
    1654             :             EVT_ID_USER_REMOVED_FROM_LOCAL_GROUP,
    1655             :             get_remove_member_event(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP));
    1656             : 
    1657           1 :         assert_int_equal(
    1658             :             EVT_ID_USER_REMOVED_FROM_UNIVERSAL_GROUP,
    1659             :             get_remove_member_event(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP));
    1660             : 
    1661           1 :         assert_int_equal(EVT_ID_NONE, get_remove_member_event(0));
    1662             : 
    1663           1 :         assert_int_equal(EVT_ID_NONE, get_remove_member_event(UINT32_MAX));
    1664           1 : }
    1665             : 
    1666             : /* test log_group_membership_changes
    1667             :  *
    1668             :  * Happy path test case
    1669             :  *
    1670             :  */
    1671           1 : static void test_log_group_membership_changes(void **state)
    1672             : {
    1673           1 :         struct ldb_context *ldb = NULL;
    1674           1 :         struct ldb_module  *module = NULL;
    1675           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1676           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1677           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1678           1 :         const char * const IP = "127.0.0.1";
    1679           1 :         struct ldb_request *req = NULL;
    1680           1 :         struct ldb_message *msg = NULL;
    1681           1 :         struct ldb_message_element *el = NULL;
    1682           1 :         struct audit_callback_context *acc = NULL;
    1683           1 :         struct ldb_result *res = NULL;
    1684           1 :         struct ldb_message *new_msg = NULL;
    1685           1 :         struct ldb_message_element *group_type = NULL;
    1686           1 :         const char *group_type_str = NULL;
    1687           1 :         struct ldb_message_element *new_el = NULL;
    1688           1 :         struct ldb_message_element *old_el = NULL;
    1689           1 :         int status = 0;
    1690           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1691             : 
    1692           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1693             : 
    1694             :         /*
    1695             :          * Build the ldb message
    1696             :          */
    1697           1 :         msg = talloc_zero(ctx, struct ldb_message);
    1698             : 
    1699             :         /*
    1700             :          * Populate message elements, adding a new entry to the membership list
    1701             :          *
    1702             :          */
    1703             : 
    1704           1 :         el = talloc_zero(ctx, struct ldb_message_element);
    1705           1 :         el->name = "member";
    1706           1 :         el->num_values = 1;
    1707           1 :         el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1708           1 :         el->values[0] = data_blob_string_const(
    1709             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1710             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1711             :                 "DC=example,DC=com");
    1712           1 :         msg->elements = el;
    1713           1 :         msg->num_elements = 1;
    1714             : 
    1715             :         /*
    1716             :          * Build the ldb_request
    1717             :          */
    1718           1 :         req = talloc_zero(ctx, struct ldb_request);
    1719           1 :         req->operation = LDB_ADD;
    1720           1 :         req->op.add.message = msg;
    1721           1 :         add_transaction_id(req, TRANSACTION);
    1722             : 
    1723             :         /*
    1724             :          * Build the initial state of the database
    1725             :          */
    1726           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1727           1 :         old_el->name = "member";
    1728           1 :         old_el->num_values = 1;
    1729           1 :         old_el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1730           1 :         old_el->values[0] = data_blob_string_const(
    1731             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1732             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1733             :                 "DC=samba,DC=example,DC=com");
    1734             : 
    1735             :         /*
    1736             :          * Build the updated state of the database
    1737             :          */
    1738           1 :         res = talloc_zero(ctx, struct ldb_result);
    1739           1 :         new_msg = talloc_zero(ctx, struct ldb_message);
    1740           1 :         new_el = talloc_zero(ctx, struct ldb_message_element);
    1741           1 :         new_el->name = "member";
    1742           1 :         new_el->num_values = 2;
    1743           1 :         new_el->values = talloc_zero_array(ctx, DATA_BLOB, 2);
    1744           1 :         new_el->values[0] = data_blob_string_const(
    1745             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1746             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1747             :                 "DC=samba,DC=example,DC=com");
    1748           1 :         new_el->values[1] = data_blob_string_const(
    1749             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1750             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1751             :                 "DC=example,DC=com");
    1752             : 
    1753           1 :         group_type = talloc_zero(ctx, struct ldb_message_element);
    1754           1 :         group_type->name = "groupType";
    1755           1 :         group_type->num_values = 1;
    1756           1 :         group_type->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1757           1 :         group_type_str = talloc_asprintf(ctx, "%u", GTYPE_SECURITY_GLOBAL_GROUP);
    1758           1 :         group_type->values[0] = data_blob_string_const(group_type_str);
    1759             : 
    1760             : 
    1761           1 :         new_msg->elements = talloc_zero_array(ctx, struct ldb_message_element, 2);
    1762           1 :         new_msg->num_elements = 2;
    1763           1 :         new_msg->elements[0] = *new_el;
    1764           1 :         new_msg->elements[1] = *group_type;
    1765             : 
    1766           1 :         res->count = 1;
    1767           1 :         res->msgs = &new_msg;
    1768             : 
    1769           1 :         acc = talloc_zero(ctx, struct audit_callback_context);
    1770           1 :         acc->request = req;
    1771           1 :         acc->module = module;
    1772           1 :         acc->members = old_el;
    1773             :         /*
    1774             :          * call log_membership_changes
    1775             :          */
    1776           1 :         messages_sent = 0;
    1777           1 :         g_result = res;
    1778           1 :         g_status = LDB_SUCCESS;
    1779           1 :         log_group_membership_changes(acc, status);
    1780           1 :         g_result = NULL;
    1781             : 
    1782             :         /*
    1783             :          * Check the results
    1784             :          */
    1785           1 :         assert_int_equal(1, messages_sent);
    1786             : 
    1787           1 :         check_group_change_message(
    1788             :             0,
    1789             :             "CN=testuser131953,CN=Users,DC=addom,DC=samba,DC=example,DC=com",
    1790             :             "Added",
    1791           1 :             EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP);
    1792             : 
    1793             :         /*
    1794             :          * Clean up
    1795             :          */
    1796           1 :         json_free(&messages[0]);
    1797           1 :         TALLOC_FREE(ctx);
    1798           1 : }
    1799             : 
    1800             : /* test log_group_membership_changes
    1801             :  *
    1802             :  * The ldb query to retrieve the new values failed.
    1803             :  *
    1804             :  * Should generate group membership change Failure message.
    1805             :  *
    1806             :  */
    1807           1 : static void test_log_group_membership_changes_read_new_failure(void **state)
    1808             : {
    1809           1 :         struct ldb_context *ldb = NULL;
    1810           1 :         struct ldb_module  *module = NULL;
    1811           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1812           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1813           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1814           1 :         const char * const IP = "127.0.0.1";
    1815           1 :         struct ldb_request *req = NULL;
    1816           1 :         struct ldb_message *msg = NULL;
    1817           1 :         struct ldb_message_element *el = NULL;
    1818           1 :         struct audit_callback_context *acc = NULL;
    1819           1 :         struct ldb_message_element *old_el = NULL;
    1820           1 :         int status = 0;
    1821           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1822             : 
    1823           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1824             : 
    1825             :         /*
    1826             :          * Build the ldb message
    1827             :          */
    1828           1 :         msg = talloc_zero(ctx, struct ldb_message);
    1829             : 
    1830             :         /*
    1831             :          * Populate message elements, adding a new entry to the membership list
    1832             :          *
    1833             :          */
    1834             : 
    1835           1 :         el = talloc_zero(ctx, struct ldb_message_element);
    1836           1 :         el->name = "member";
    1837           1 :         el->num_values = 1;
    1838           1 :         el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1839           1 :         el->values[0] = data_blob_string_const(
    1840             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1841             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1842             :                 "DC=example,DC=com");
    1843           1 :         msg->elements = el;
    1844           1 :         msg->num_elements = 1;
    1845             : 
    1846             :         /*
    1847             :          * Build the ldb_request
    1848             :          */
    1849           1 :         req = talloc_zero(ctx, struct ldb_request);
    1850           1 :         req->operation = LDB_ADD;
    1851           1 :         req->op.add.message = msg;
    1852           1 :         add_transaction_id(req, TRANSACTION);
    1853             : 
    1854             :         /*
    1855             :          * Build the initial state of the database
    1856             :          */
    1857           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1858           1 :         old_el->name = "member";
    1859           1 :         old_el->num_values = 1;
    1860           1 :         old_el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1861           1 :         old_el->values[0] = data_blob_string_const(
    1862             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1863             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1864             :                 "DC=samba,DC=example,DC=com");
    1865             : 
    1866           1 :         acc = talloc_zero(ctx, struct audit_callback_context);
    1867           1 :         acc->request = req;
    1868           1 :         acc->module = module;
    1869           1 :         acc->members = old_el;
    1870             :         /*
    1871             :          * call log_membership_changes
    1872             :          */
    1873           1 :         messages_sent = 0;
    1874           1 :         g_result = NULL;
    1875           1 :         g_status = LDB_ERR_NO_SUCH_OBJECT;
    1876           1 :         log_group_membership_changes(acc, status);
    1877             : 
    1878             :         /*
    1879             :          * Check the results
    1880             :          */
    1881           1 :         assert_int_equal(1, messages_sent);
    1882             : 
    1883           1 :         check_group_change_message(
    1884             :             0,
    1885             :             "",
    1886             :             "Failure",
    1887           1 :             EVT_ID_NONE);
    1888             : 
    1889             :         /*
    1890             :          * Clean up
    1891             :          */
    1892           1 :         json_free(&messages[0]);
    1893           1 :         TALLOC_FREE(ctx);
    1894           1 : }
    1895             : 
    1896             : /* test log_group_membership_changes
    1897             :  *
    1898             :  * The operation failed.
    1899             :  *
    1900             :  * Should generate group membership change Failure message.
    1901             :  *
    1902             :  */
    1903           1 : static void test_log_group_membership_changes_error(void **state)
    1904             : {
    1905           1 :         struct ldb_context *ldb = NULL;
    1906           1 :         struct ldb_module  *module = NULL;
    1907           1 :         const char * const SID = "S-1-5-21-2470180966-3899876309-2637894779";
    1908           1 :         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1909           1 :         const char * const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
    1910           1 :         const char * const IP = "127.0.0.1";
    1911           1 :         struct ldb_request *req = NULL;
    1912           1 :         struct ldb_message *msg = NULL;
    1913           1 :         struct ldb_message_element *el = NULL;
    1914           1 :         struct ldb_message_element *old_el = NULL;
    1915           1 :         struct audit_callback_context *acc = NULL;
    1916           1 :         int status = LDB_ERR_OPERATIONS_ERROR;
    1917           1 :         TALLOC_CTX *ctx = talloc_new(NULL);
    1918             : 
    1919           1 :         setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
    1920             : 
    1921             :         /*
    1922             :          * Build the ldb message
    1923             :          */
    1924           1 :         msg = talloc_zero(ctx, struct ldb_message);
    1925             : 
    1926             :         /*
    1927             :          * Populate message elements, adding a new entry to the membership list
    1928             :          *
    1929             :          */
    1930             : 
    1931           1 :         el = talloc_zero(ctx, struct ldb_message_element);
    1932           1 :         el->name = "member";
    1933           1 :         el->num_values = 1;
    1934           1 :         el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1935           1 :         el->values[0] = data_blob_string_const(
    1936             :                 "<GUID=081519b5-a709-44a0-bc95-dd4bfe809bf8>;"
    1937             :                 "CN=testuser131953,CN=Users,DC=addom,DC=samba,"
    1938             :                 "DC=example,DC=com");
    1939           1 :         msg->elements = el;
    1940           1 :         msg->num_elements = 1;
    1941             : 
    1942             :         /*
    1943             :          * Build the ldb_request
    1944             :          */
    1945           1 :         req = talloc_zero(ctx, struct ldb_request);
    1946           1 :         req->operation = LDB_ADD;
    1947           1 :         req->op.add.message = msg;
    1948           1 :         add_transaction_id(req, TRANSACTION);
    1949             : 
    1950             :         /*
    1951             :          * Build the initial state of the database
    1952             :          */
    1953           1 :         old_el = talloc_zero(ctx, struct ldb_message_element);
    1954           1 :         old_el->name = "member";
    1955           1 :         old_el->num_values = 1;
    1956           1 :         old_el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
    1957           1 :         old_el->values[0] = data_blob_string_const(
    1958             :                 "<GUID=cb8c2777-dcf5-419c-ab57-f645dbdf681b>;"
    1959             :                 "cn=grpadttstuser01,cn=users,DC=addom,"
    1960             :                 "DC=samba,DC=example,DC=com");
    1961             : 
    1962             : 
    1963           1 :         acc = talloc_zero(ctx, struct audit_callback_context);
    1964           1 :         acc->request = req;
    1965           1 :         acc->module = module;
    1966           1 :         acc->members = old_el;
    1967             :         /*
    1968             :          * call log_membership_changes
    1969             :          */
    1970           1 :         messages_sent = 0;
    1971           1 :         log_group_membership_changes(acc, status);
    1972             : 
    1973             :         /*
    1974             :          * Check the results
    1975             :          */
    1976           1 :         assert_int_equal(1, messages_sent);
    1977             : 
    1978           1 :         check_group_change_message(
    1979             :             0,
    1980             :             "",
    1981             :             "Failure",
    1982           1 :             EVT_ID_NONE);
    1983             : 
    1984             :         /*
    1985             :          * Clean up
    1986             :          */
    1987           1 :         json_free(&messages[0]);
    1988           1 :         TALLOC_FREE(ctx);
    1989           1 : }
    1990             : 
    1991             : /*
    1992             :  * Note: to run under valgrind us:
    1993             :  *       valgrind --suppressions=test_group_audit.valgrind bin/test_group_audit
    1994             :  *       This suppresses the errors generated because the ldb_modules are not
    1995             :  *       de-registered.
    1996             :  *
    1997             :  */
    1998           1 : int main(void) {
    1999           1 :         const struct CMUnitTest tests[] = {
    2000             :             cmocka_unit_test(test_audit_group_json),
    2001             :             cmocka_unit_test(test_audit_group_json_error),
    2002             :             cmocka_unit_test(test_audit_group_json_no_event),
    2003             :             cmocka_unit_test(test_get_transaction_id),
    2004             :             cmocka_unit_test(test_audit_group_hr),
    2005             :             cmocka_unit_test(test_get_parsed_dns),
    2006             :             cmocka_unit_test(test_dn_compare),
    2007             :             cmocka_unit_test(test_get_primary_group_dn),
    2008             :             cmocka_unit_test(test_log_membership_changes_removed),
    2009             :             cmocka_unit_test(test_log_membership_changes_remove_all),
    2010             :             cmocka_unit_test(test_log_membership_changes_added),
    2011             :             cmocka_unit_test(test_log_membership_changes_add_to_empty),
    2012             :             cmocka_unit_test(test_log_membership_changes_rmd_flags),
    2013             :             cmocka_unit_test(test_get_add_member_event),
    2014             :             cmocka_unit_test(test_get_remove_member_event),
    2015             :             cmocka_unit_test(test_log_group_membership_changes),
    2016             :             cmocka_unit_test(test_log_group_membership_changes_read_new_failure),
    2017             :             cmocka_unit_test(test_log_group_membership_changes_error),
    2018             :         };
    2019             : 
    2020           1 :         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
    2021           1 :         return cmocka_run_group_tests(tests, NULL, NULL);
    2022             : }

Generated by: LCOV version 1.14