Coverage Report

Created: 2026-06-07 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/librpc/ndr/ndr_table.c
Line
Count
Source
1
/* 
2
   Unix SMB/CIFS implementation.
3
4
   dcerpc utility functions
5
6
   Copyright (C) Andrew Tridgell 2003
7
   Copyright (C) Jelmer Vernooij 2004
8
   
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
   
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
   
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
*/
22
23
#include "includes.h"
24
#include "../lib/util/dlinklist.h"
25
#include "librpc/ndr/libndr.h"
26
#include "librpc/ndr/ndr_table.h"
27
#undef strcasecmp
28
29
static struct ndr_interface_list *ndr_interfaces;
30
31
/*
32
  register a ndr interface table
33
*/
34
NTSTATUS ndr_table_register(const struct ndr_interface_table *table)
35
0
{
36
0
  struct ndr_interface_list *l;
37
38
0
  for (l = ndr_interfaces; l; l = l->next) {
39
    /*
40
     * If no GUID is supplied, use the name to determine
41
     * uniqueness.
42
     */
43
0
    if (GUID_all_zero(&table->syntax_id.uuid)) {
44
0
      if (strcmp(table->name,
45
0
           l->table->name) != 0) {
46
0
        continue;
47
0
      }
48
0
      DBG_ERR("Attempt to register interface %s which has the "
49
0
        "same name as already registered interface\n",
50
0
        table->name);
51
0
    } else {
52
0
      if (!GUID_equal(&table->syntax_id.uuid,
53
0
          &l->table->syntax_id.uuid)) {
54
0
        continue;
55
0
      }
56
0
      DBG_ERR("Attempt to register interface %s which has the "
57
0
        "same UUID as already registered interface %s\n",
58
0
        table->name, l->table->name);
59
0
    }
60
0
    return NT_STATUS_OBJECT_NAME_COLLISION;
61
0
  }
62
63
  /*
64
   * This is a singleton instance guaranteed
65
   * by the above check to be only added once
66
   * into the list so we can allocate off the NULL
67
   * context. We never want this to be freed
68
   * until process shutdown. If needed we could
69
   * add a deregister function that walks and
70
   * frees the list.
71
   */
72
73
0
  l = talloc(NULL, struct ndr_interface_list);
74
0
  l->table = table;
75
76
0
  DLIST_ADD(ndr_interfaces, l);
77
78
0
    return NT_STATUS_OK;
79
0
}
80
81
/*
82
  find the pipe name for a local IDL interface
83
*/
84
const char *ndr_interface_name(const struct GUID *uuid, uint32_t if_version)
85
0
{
86
0
  const struct ndr_interface_list *l;
87
0
  for (l=ndr_table_list();l;l=l->next) {
88
0
    if (GUID_equal(&l->table->syntax_id.uuid, uuid) &&
89
0
        l->table->syntax_id.if_version == if_version) {
90
0
      return l->table->name;
91
0
    }
92
0
  }
93
0
  return "UNKNOWN";
94
0
}
95
96
/*
97
  find the number of calls defined by local IDL
98
*/
99
int ndr_interface_num_calls(const struct GUID *uuid, uint32_t if_version)
100
0
{
101
0
  const struct ndr_interface_list *l;
102
0
  for (l=ndr_table_list();l;l=l->next){
103
0
    if (GUID_equal(&l->table->syntax_id.uuid, uuid) &&
104
0
        l->table->syntax_id.if_version == if_version) {
105
0
      return l->table->num_calls;
106
0
    }
107
0
  }
108
0
  return -1;
109
0
}
110
111
112
/*
113
  find a dcerpc interface by name
114
*/
115
const struct ndr_interface_table *ndr_table_by_name(const char *name)
116
0
{
117
0
  const struct ndr_interface_list *l;
118
0
  for (l=ndr_table_list();l;l=l->next) {
119
0
    if (strcasecmp(l->table->name, name) == 0) {
120
0
      return l->table;
121
0
    }
122
0
  }
123
0
  return NULL;
124
0
}
125
126
/*
127
  find a dcerpc interface by syntax
128
*/
129
const struct ndr_interface_table *ndr_table_by_syntax(const struct ndr_syntax_id *syntax)
130
0
{
131
0
  const struct ndr_interface_list *l;
132
0
  if (GUID_all_zero(&syntax->uuid)) {
133
    /* These are not unique */
134
0
    return NULL;
135
0
  }
136
0
  for (l=ndr_table_list();l;l=l->next) {
137
0
    if (ndr_syntax_id_equal(&l->table->syntax_id, syntax)) {
138
0
      return l->table;
139
0
    }
140
0
  }
141
0
  return NULL;
142
0
}
143
144
/*
145
  find a dcerpc interface by uuid
146
*/
147
const struct ndr_interface_table *ndr_table_by_uuid(const struct GUID *uuid)
148
0
{
149
0
  const struct ndr_interface_list *l;
150
0
  if (GUID_all_zero(uuid)) {
151
    /* These are not unique */
152
0
    return NULL;
153
0
  }
154
0
  for (l=ndr_table_list();l;l=l->next) {
155
0
    if (GUID_equal(&l->table->syntax_id.uuid, uuid)) {
156
0
      return l->table;
157
0
    }
158
0
  }
159
0
  return NULL;
160
0
}
161
162
/*
163
  return the list of registered dcerpc_pipes
164
*/
165
const struct ndr_interface_list *ndr_table_list(void)
166
0
{
167
0
  ndr_table_init();
168
0
  return ndr_interfaces;
169
0
}
170
171
172
NTSTATUS ndr_table_init(void)
173
0
{
174
0
  static bool initialized = false;
175
176
0
  if (initialized) return NT_STATUS_OK;
177
0
  initialized = true;
178
179
0
  ndr_table_register_builtin_tables();
180
181
0
  return NT_STATUS_OK;
182
0
}