Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/libads/ads_status.c
Line
Count
Source
1
/* 
2
   Unix SMB/CIFS implementation.
3
   ads (active directory) utility library
4
   Copyright (C) Andrew Tridgell 2001
5
   Copyright (C) Remus Koos 2001
6
   Copyright (C) Andrew Bartlett 2001
7
   
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 "smb_krb5.h"
25
#include "system/gssapi.h"
26
#include "smb_ldap.h"
27
#include "libads/ads_status.h"
28
29
/*
30
  build a ADS_STATUS structure
31
*/
32
ADS_STATUS ads_build_error(enum ads_error_type etype, 
33
         int rc, int minor_status)
34
0
{
35
0
  ADS_STATUS ret;
36
37
0
  if (etype == ENUM_ADS_ERROR_NT) {
38
0
    DEBUG(0,("don't use ads_build_error with ENUM_ADS_ERROR_NT!\n"));
39
0
    ret.err.rc = -1;
40
0
    ret.error_type = ENUM_ADS_ERROR_SYSTEM;
41
0
    ret.minor_status = 0;
42
0
    return ret; 
43
0
  } 
44
    
45
0
  ret.err.rc = rc;
46
0
  ret.error_type = etype;   
47
0
  ret.minor_status = minor_status;
48
0
  return ret;
49
0
}
50
51
ADS_STATUS ads_build_nt_error(enum ads_error_type etype, 
52
         NTSTATUS nt_status)
53
0
{
54
0
  ADS_STATUS ret;
55
56
0
  if (etype != ENUM_ADS_ERROR_NT) {
57
0
    DEBUG(0,("don't use ads_build_nt_error without ENUM_ADS_ERROR_NT!\n"));
58
0
    ret.err.rc = -1;
59
0
    ret.error_type = ENUM_ADS_ERROR_SYSTEM;
60
0
    ret.minor_status = 0;
61
0
    return ret; 
62
0
  }
63
0
  ret.err.nt_status = nt_status;
64
0
  ret.error_type = etype;   
65
0
  ret.minor_status = 0;
66
0
  return ret;
67
0
}
68
69
/*
70
  do a rough conversion between ads error codes and NT status codes
71
  we'll need to fill this in more
72
*/
73
NTSTATUS ads_ntstatus(ADS_STATUS status)
74
0
{
75
0
  switch (status.error_type) {
76
0
  case ENUM_ADS_ERROR_NT:
77
0
    return status.err.nt_status; 
78
0
  case ENUM_ADS_ERROR_SYSTEM:
79
0
    return map_nt_error_from_unix(status.err.rc);
80
0
#ifdef HAVE_LDAP
81
0
  case ENUM_ADS_ERROR_LDAP:
82
0
    if (status.err.rc == LDAP_SUCCESS) {
83
0
      return NT_STATUS_OK;
84
0
    }
85
0
    if (status.err.rc == LDAP_TIMELIMIT_EXCEEDED) {
86
0
      return NT_STATUS_IO_TIMEOUT;
87
0
    }
88
0
    return NT_STATUS_LDAP(status.err.rc);
89
0
#endif
90
0
#ifdef HAVE_KRB5
91
0
  case ENUM_ADS_ERROR_KRB5:
92
0
    return krb5_to_nt_status(status.err.rc);
93
0
#endif
94
0
  default:
95
0
    break;
96
0
  }
97
98
0
  if (ADS_ERR_OK(status)) {
99
0
    return NT_STATUS_OK;
100
0
  }
101
0
  return NT_STATUS_UNSUCCESSFUL;
102
0
}
103
104
/*
105
  return a string for an error from a ads routine
106
*/
107
const char *ads_errstr(ADS_STATUS status)
108
0
{
109
0
  switch (status.error_type) {
110
0
  case ENUM_ADS_ERROR_SYSTEM:
111
0
    return strerror(status.err.rc);
112
0
#ifdef HAVE_LDAP
113
0
  case ENUM_ADS_ERROR_LDAP:
114
0
    return ldap_err2string(status.err.rc);
115
0
#endif
116
0
#ifdef HAVE_KRB5
117
0
  case ENUM_ADS_ERROR_KRB5: 
118
0
    return error_message(status.err.rc);
119
0
  case ENUM_ADS_ERROR_GSS:
120
0
  {
121
0
    char *ret;
122
0
    uint32_t msg_ctx;
123
0
    uint32_t minor;
124
0
    gss_buffer_desc msg1, msg2;
125
126
0
    msg_ctx = 0;
127
    
128
0
    msg1.value = NULL;
129
0
    msg2.value = NULL;
130
0
    gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE,
131
0
           GSS_C_NULL_OID, &msg_ctx, &msg1);
132
0
    gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE,
133
0
           GSS_C_NULL_OID, &msg_ctx, &msg2);
134
0
    ret = talloc_asprintf(talloc_tos(), "%s : %s",
135
0
              (char *)msg1.value, (char *)msg2.value);
136
0
    SMB_ASSERT(ret != NULL);
137
0
    gss_release_buffer(&minor, &msg1);
138
0
    gss_release_buffer(&minor, &msg2);
139
0
    return ret;
140
0
  }
141
0
#endif
142
0
  case ENUM_ADS_ERROR_NT: 
143
0
    return get_friendly_nt_error_msg(ads_ntstatus(status));
144
0
  default:
145
0
    return "Unknown ADS error type!? (not compiled in?)";
146
0
  }
147
0
}
148
149
#ifdef HAVE_KRB5
150
NTSTATUS gss_err_to_ntstatus(uint32_t maj, uint32_t min)
151
0
{
152
0
        ADS_STATUS adss = ADS_ERROR_GSS(maj, min);
153
        DEBUG(10,("gss_err_to_ntstatus: Error %s\n",
154
0
                ads_errstr(adss) ));
155
0
        return ads_ntstatus(adss);
156
0
}
157
#endif