Line data Source code
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 9565 : ADS_STATUS ads_build_error(enum ads_error_type etype, 33 : int rc, int minor_status) 34 : { 35 0 : ADS_STATUS ret; 36 : 37 9565 : 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 : } 44 : 45 9565 : ret.err.rc = rc; 46 9565 : ret.error_type = etype; 47 9565 : ret.minor_status = minor_status; 48 9565 : return ret; 49 : } 50 : 51 1585 : ADS_STATUS ads_build_nt_error(enum ads_error_type etype, 52 : NTSTATUS nt_status) 53 : { 54 0 : ADS_STATUS ret; 55 : 56 1585 : 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 : } 63 1585 : ret.err.nt_status = nt_status; 64 1585 : ret.error_type = etype; 65 1585 : ret.minor_status = 0; 66 1585 : return ret; 67 : } 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 390 : NTSTATUS ads_ntstatus(ADS_STATUS status) 74 : { 75 390 : switch (status.error_type) { 76 390 : case ENUM_ADS_ERROR_NT: 77 390 : return status.err.nt_status; 78 0 : case ENUM_ADS_ERROR_SYSTEM: 79 0 : return map_nt_error_from_unix(status.err.rc); 80 : #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 : } 85 0 : if (status.err.rc == LDAP_TIMELIMIT_EXCEEDED) { 86 0 : return NT_STATUS_IO_TIMEOUT; 87 : } 88 0 : return NT_STATUS_LDAP(status.err.rc); 89 : #endif 90 : #ifdef HAVE_KRB5 91 0 : case ENUM_ADS_ERROR_KRB5: 92 0 : return krb5_to_nt_status(status.err.rc); 93 : #endif 94 0 : default: 95 0 : break; 96 : } 97 : 98 0 : if (ADS_ERR_OK(status)) { 99 0 : return NT_STATUS_OK; 100 : } 101 0 : return NT_STATUS_UNSUCCESSFUL; 102 : } 103 : 104 : /* 105 : return a string for an error from a ads routine 106 : */ 107 7 : const char *ads_errstr(ADS_STATUS status) 108 : { 109 7 : switch (status.error_type) { 110 0 : case ENUM_ADS_ERROR_SYSTEM: 111 0 : return strerror(status.err.rc); 112 : #ifdef HAVE_LDAP 113 0 : case ENUM_ADS_ERROR_LDAP: 114 0 : return ldap_err2string(status.err.rc); 115 : #endif 116 : #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 : { 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 : GSS_C_NULL_OID, &msg_ctx, &msg1); 132 0 : gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, 133 : 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 : } 141 : #endif 142 7 : case ENUM_ADS_ERROR_NT: 143 7 : return get_friendly_nt_error_msg(ads_ntstatus(status)); 144 0 : default: 145 0 : return "Unknown ADS error type!? (not compiled in?)"; 146 : } 147 : } 148 : 149 : #ifdef HAVE_KRB5 150 0 : NTSTATUS gss_err_to_ntstatus(uint32_t maj, uint32_t min) 151 : { 152 0 : ADS_STATUS adss = ADS_ERROR_GSS(maj, min); 153 0 : DEBUG(10,("gss_err_to_ntstatus: Error %s\n", 154 : ads_errstr(adss) )); 155 0 : return ads_ntstatus(adss); 156 : } 157 : #endif