| File: | daemons/ipa-sam/ipa_sam.c |
| Warning: | line 4447, column 11 Value stored to 'status' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | #define HAVE_IMMEDIATE_STRUCTURES1 1 |
| 2 | #define LDAP_DEPRECATED1 1 |
| 3 | |
| 4 | #include "config.h" |
| 5 | #include <stdbool.h> |
| 6 | #include <stdint.h> |
| 7 | #include <stdio.h> |
| 8 | #include <unistd.h> |
| 9 | #include <sys/types.h> |
| 10 | #include <pwd.h> |
| 11 | #include <errno(*__errno_location ()).h> |
| 12 | #include <ldap.h> |
| 13 | #include <krb5/krb5.h> |
| 14 | |
| 15 | #include <talloc.h> |
| 16 | |
| 17 | #include <param.h> |
| 18 | #include <ndr.h> |
| 19 | #include <util/data_blob.h> |
| 20 | #include <util/time.h> |
| 21 | #include <util/debug.h> |
| 22 | |
| 23 | #ifndef _SAMBA_UTIL_H_ |
| 24 | bool_Bool trim_string(char *s, const char *front, const char *back); |
| 25 | char *smb_xstrdup(const char *s); |
| 26 | #endif |
| 27 | |
| 28 | #include <core/ntstatus.h> |
| 29 | #include <gen_ndr/security.h> |
| 30 | #include <smbldap.h> |
| 31 | |
| 32 | #include <gen_ndr/samr.h> |
| 33 | |
| 34 | #include <passdb.h> |
| 35 | |
| 36 | #include <sasl/sasl.h> |
| 37 | #include <krb5/krb5.h> |
| 38 | #include <sss_idmap.h> |
| 39 | #include "ipa_asn1.h" |
| 40 | #include "ipa_pwd.h" |
| 41 | #include "ipa_mspac.h" |
| 42 | |
| 43 | /* from drsblobs.h */ |
| 44 | struct AuthInfoNone { |
| 45 | uint32_t size;/* [value(0)] */ |
| 46 | }; |
| 47 | |
| 48 | struct AuthInfoNT4Owf { |
| 49 | uint32_t size;/* [value(16)] */ |
| 50 | struct samr_Password password; |
| 51 | }; |
| 52 | |
| 53 | struct AuthInfoClear { |
| 54 | uint32_t size; |
| 55 | uint8_t *password; |
| 56 | }; |
| 57 | |
| 58 | struct AuthInfoVersion { |
| 59 | uint32_t size;/* [value(4)] */ |
| 60 | uint32_t version; |
| 61 | }; |
| 62 | |
| 63 | union AuthInfo { |
| 64 | struct AuthInfoNone none;/* [case(TRUST_AUTH_TYPE_NONE)] */ |
| 65 | struct AuthInfoNT4Owf nt4owf;/* [case(TRUST_AUTH_TYPE_NT4OWF)] */ |
| 66 | struct AuthInfoClear clear;/* [case(TRUST_AUTH_TYPE_CLEAR)] */ |
| 67 | struct AuthInfoVersion version;/* [case(TRUST_AUTH_TYPE_VERSION)] */ |
| 68 | }/* [nodiscriminant] */; |
| 69 | |
| 70 | struct AuthenticationInformation { |
| 71 | NTTIME LastUpdateTime; |
| 72 | enum lsa_TrustAuthType AuthType; |
| 73 | union AuthInfo AuthInfo;/* [switch_is(AuthType)] */ |
| 74 | DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN4)] */ |
| 75 | }/* [public] */; |
| 76 | |
| 77 | struct AuthenticationInformationArray { |
| 78 | uint32_t count; |
| 79 | struct AuthenticationInformation *array; |
| 80 | }/* [gensize,nopush,public,nopull] */; |
| 81 | |
| 82 | struct trustAuthInOutBlob { |
| 83 | uint32_t count; |
| 84 | uint32_t current_offset;/* [value((count>0)?12:0)] */ |
| 85 | uint32_t previous_offset;/* [value((count>0)?12+ndr_size_AuthenticationInformationArray(¤t,ndr->flags):0)] */ |
| 86 | struct AuthenticationInformationArray current;/* [subcontext_size((previous_offset)-(current_offset)),subcontext(0)] */ |
| 87 | struct AuthenticationInformationArray previous;/* [subcontext(0),flag(LIBNDR_FLAG_REMAINING)] */ |
| 88 | }/* [gensize,public,nopush] */; |
| 89 | |
| 90 | /* from generated idmap.h - hopefully OK */ |
| 91 | enum id_type { |
| 92 | ID_TYPE_NOT_SPECIFIED, |
| 93 | ID_TYPE_UID, |
| 94 | ID_TYPE_GID, |
| 95 | ID_TYPE_BOTH |
| 96 | }; |
| 97 | |
| 98 | struct unixid { |
| 99 | uint32_t id; |
| 100 | enum id_type type; |
| 101 | }/* [public] */; |
| 102 | |
| 103 | enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r); /*available in libndr-samba.so */ |
| 104 | bool_Bool sid_check_is_builtin(const struct dom_sid *sid); /* available in libpdb.so */ |
| 105 | /* available in libpdb.so, renamed from sid_check_is_domain() in c43505b621725c9a754f0ee98318d451b093f2ed */ |
| 106 | bool_Bool sid_linearize(char *outbuf, size_t len, const struct dom_sid *sid); /* available in libsmbconf.so */ |
| 107 | char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s); /* available in libsmbconf.so */ |
| 108 | bool_Bool secrets_store(const char *key, const void *data, size_t size); /* available in libpdb.so */ |
| 109 | void idmap_cache_set_sid2unixid(const struct dom_sid *sid, struct unixid *unix_id); /* available in libsmbconf.so */ |
| 110 | bool_Bool E_md4hash(const char *passwd, uint8_t p16[16]); /* available in libcliauth-samba4.so */ |
| 111 | |
| 112 | #define LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs" "ipaNTUserAttrs" |
| 113 | #define LDAP_OBJ_TRUSTED_DOMAIN"ipaNTTrustedDomain" "ipaNTTrustedDomain" |
| 114 | #define LDAP_OBJ_ID_OBJECT"ipaIDobject" "ipaIDobject" |
| 115 | #define LDAP_ATTRIBUTE_TRUST_SID"ipaNTTrustedDomainSID" "ipaNTTrustedDomainSID" |
| 116 | #define LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier" "ipaNTSecurityIdentifier" |
| 117 | #define LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs" "ipaNTGroupAttrs" |
| 118 | |
| 119 | #define IPA_KEYTAB_SET_OID"2.16.840.1.113730.3.8.10.1" "2.16.840.1.113730.3.8.10.1" |
| 120 | #define IPA_KEYTAB_SET_OID_OLD"2.16.840.1.113730.3.8.3.1" "2.16.840.1.113730.3.8.3.1" |
| 121 | #define IPA_MAGIC_ID_STR"-1" "-1" |
| 122 | |
| 123 | #define LDAP_ATTRIBUTE_CN"cn" "cn" |
| 124 | #define LDAP_ATTRIBUTE_UID"uid" "uid" |
| 125 | #define LDAP_ATTRIBUTE_TRUST_TYPE"ipaNTTrustType" "ipaNTTrustType" |
| 126 | #define LDAP_ATTRIBUTE_TRUST_ATTRIBUTES"ipaNTTrustAttributes" "ipaNTTrustAttributes" |
| 127 | #define LDAP_ATTRIBUTE_TRUST_DIRECTION"ipaNTTrustDirection" "ipaNTTrustDirection" |
| 128 | #define LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET"ipaNTTrustPosixOffset" "ipaNTTrustPosixOffset" |
| 129 | #define LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE"ipaNTSupportedEncryptionTypes" "ipaNTSupportedEncryptionTypes" |
| 130 | #define LDAP_ATTRIBUTE_TRUST_PARTNER"ipaNTTrustPartner" "ipaNTTrustPartner" |
| 131 | #define LDAP_ATTRIBUTE_FLAT_NAME"ipaNTFlatName" "ipaNTFlatName" |
| 132 | #define LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING"ipaNTTrustAuthOutgoing" "ipaNTTrustAuthOutgoing" |
| 133 | #define LDAP_ATTRIBUTE_TRUST_AUTH_INCOMING"ipaNTTrustAuthIncoming" "ipaNTTrustAuthIncoming" |
| 134 | #define LDAP_ATTRIBUTE_SECURITY_IDENTIFIER"ipaNTSecurityIdentifier" "ipaNTSecurityIdentifier" |
| 135 | #define LDAP_ATTRIBUTE_TRUST_FOREST_TRUST_INFO"ipaNTTrustForestTrustInfo" "ipaNTTrustForestTrustInfo" |
| 136 | #define LDAP_ATTRIBUTE_FALLBACK_PRIMARY_GROUP"ipaNTFallbackPrimaryGroup" "ipaNTFallbackPrimaryGroup" |
| 137 | #define LDAP_ATTRIBUTE_OBJECTCLASS"objectClass" "objectClass" |
| 138 | #define LDAP_ATTRIBUTE_HOME_DRIVE"ipaNTHomeDirectoryDrive" "ipaNTHomeDirectoryDrive" |
| 139 | #define LDAP_ATTRIBUTE_HOME_PATH"ipaNTHomeDirectory" "ipaNTHomeDirectory" |
| 140 | #define LDAP_ATTRIBUTE_HOMEDIRECTORY"homeDirectory" "homeDirectory" |
| 141 | #define LDAP_ATTRIBUTE_LOGON_SCRIPT"ipaNTLogonScript" "ipaNTLogonScript" |
| 142 | #define LDAP_ATTRIBUTE_PROFILE_PATH"ipaNTProfilePath" "ipaNTProfilePath" |
| 143 | #define LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING"ipaNTSIDBlacklistIncoming" "ipaNTSIDBlacklistIncoming" |
| 144 | #define LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING"ipaNTSIDBlacklistOutgoing" "ipaNTSIDBlacklistOutgoing" |
| 145 | #define LDAP_ATTRIBUTE_NTHASH"ipaNTHash" "ipaNTHash" |
| 146 | #define LDAP_ATTRIBUTE_UIDNUMBER"uidnumber" "uidnumber" |
| 147 | #define LDAP_ATTRIBUTE_GIDNUMBER"gidnumber" "gidnumber" |
| 148 | #define LDAP_ATTRIBUTE_ASSOCIATED_DOMAIN"associatedDomain" "associatedDomain" |
| 149 | |
| 150 | #define LDAP_OBJ_KRB_PRINCIPAL"krbPrincipal" "krbPrincipal" |
| 151 | #define LDAP_OBJ_KRB_PRINCIPAL_AUX"krbPrincipalAux" "krbPrincipalAux" |
| 152 | #define LDAP_OBJ_KRB_TICKET_POLICY_AUX"krbTicketPolicyAux" "krbTicketPolicyAux" |
| 153 | #define LDAP_ATTRIBUTE_KRB_CANONICAL"krbCanonicalName" "krbCanonicalName" |
| 154 | #define LDAP_ATTRIBUTE_KRB_PRINCIPAL"krbPrincipalName" "krbPrincipalName" |
| 155 | #define LDAP_ATTRIBUTE_KRB_TICKET_FLAGS"krbTicketFlags" "krbTicketFlags" |
| 156 | #define LDAP_ATTRIBUTE_IPAOPALLOW"ipaAllowedToPerform;read_keys" "ipaAllowedToPerform;read_keys" |
| 157 | |
| 158 | #define LDAP_OBJ_IPAOBJECT"ipaObject" "ipaObject" |
| 159 | #define LDAP_OBJ_IPAHOST"ipaHost" "ipaHost" |
| 160 | #define LDAP_OBJ_POSIXACCOUNT"posixAccount" "posixAccount" |
| 161 | |
| 162 | #define LDAP_OBJ_GROUPOFNAMES"groupOfNames" "groupOfNames" |
| 163 | #define LDAP_OBJ_NESTEDGROUP"nestedGroup" "nestedGroup" |
| 164 | #define LDAP_OBJ_IPAUSERGROUP"ipaUserGroup" "ipaUserGroup" |
| 165 | #define LDAP_OBJ_POSIXGROUP"posixGroup" "posixGroup" |
| 166 | #define LDAP_OBJ_DOMAINRELATED"domainRelatedObject" "domainRelatedObject" |
| 167 | #define LDAP_OBJ_IPAOPALLOW"ipaAllowedOperations" "ipaAllowedOperations" |
| 168 | |
| 169 | #define LDAP_CN_REALM_DOMAINS"cn=Realm Domains,cn=ipa,cn=etc" "cn=Realm Domains,cn=ipa,cn=etc" |
| 170 | |
| 171 | #define LDAP_CN_ADTRUST_AGENTS"cn=adtrust agents,cn=sysaccounts,cn=etc" "cn=adtrust agents,cn=sysaccounts,cn=etc" |
| 172 | #define LDAP_CN_ADTRUST_ADMINS"cn=trust admins,cn=groups,cn=accounts" "cn=trust admins,cn=groups,cn=accounts" |
| 173 | |
| 174 | #define HAS_KRB_PRINCIPAL(1<<0) (1<<0) |
| 175 | #define HAS_KRB_PRINCIPAL_AUX(1<<1) (1<<1) |
| 176 | #define HAS_IPAOBJECT(1<<2) (1<<2) |
| 177 | #define HAS_IPAHOST(1<<3) (1<<3) |
| 178 | #define HAS_POSIXACCOUNT(1<<4) (1<<4) |
| 179 | #define HAS_GROUPOFNAMES(1<<5) (1<<5) |
| 180 | #define HAS_NESTEDGROUP(1<<6) (1<<6) |
| 181 | #define HAS_IPAUSERGROUP(1<<7) (1<<7) |
| 182 | #define HAS_POSIXGROUP(1<<8) (1<<8) |
| 183 | #define HAS_KRB_TICKET_POLICY_AUX(1<<9) (1<<9) |
| 184 | |
| 185 | /* krbTicketFlags flag to don't allow issuing any ticket, keep in decimal form for LDAP use*/ |
| 186 | #define IPASAM_DISALLOW_ALL_TIX64 64 |
| 187 | |
| 188 | const struct dom_sid global_sid_Builtin = { 1, 1, {0,0,0,0,0,5}, |
| 189 | {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; |
| 190 | |
| 191 | /* With Samba 4.7 ldapsam_privates structure is not public anymore. |
| 192 | * FreeIPA needs to use own structure */ |
| 193 | |
| 194 | struct ipasam_private { |
| 195 | struct smbldap_state *ldap_state; |
| 196 | /* Former statics */ |
| 197 | LDAPMessage *result; |
| 198 | LDAPMessage *entry; |
| 199 | |
| 200 | const char *domain_name; |
| 201 | struct dom_sid domain_sid; |
| 202 | |
| 203 | char *domain_dn; |
| 204 | char *realm; |
| 205 | char *base_dn; |
| 206 | char *trust_dn; |
| 207 | char *flat_name; |
| 208 | struct dom_sid fallback_primary_group; |
| 209 | char *fallback_primary_group_gid_str; |
| 210 | char *server_princ; |
| 211 | char *client_princ; |
| 212 | struct sss_idmap_ctx *idmap_ctx; |
| 213 | uint32_t supported_enctypes; |
| 214 | bool_Bool fips_enabled; |
| 215 | }; |
| 216 | |
| 217 | |
| 218 | static NTSTATUS ipasam_get_domain_name(struct ipasam_private *ipasam_state, |
| 219 | TALLOC_CTX *mem_ctx, |
| 220 | char **domain_name); |
| 221 | |
| 222 | |
| 223 | static void *idmap_talloc(size_t size, void *pvt) |
| 224 | { |
| 225 | return talloc_size(pvt, size)talloc_named_const(pvt, size, "ipa_sam.c" ":" "225"); |
| 226 | } |
| 227 | |
| 228 | static void idmap_talloc_free(void *ptr, void *pvt) |
| 229 | { |
| 230 | talloc_free(ptr)_talloc_free(ptr, "ipa_sam.c" ":" "230"); |
| 231 | } |
| 232 | |
| 233 | static void sid_copy(struct dom_sid *dst, const struct dom_sid *src) |
| 234 | { |
| 235 | size_t c; |
| 236 | |
| 237 | memset(dst, 0, sizeof(*dst)); |
| 238 | |
| 239 | dst->sid_rev_num = src->sid_rev_num; |
| 240 | dst->num_auths = src->num_auths; |
| 241 | memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth)); |
| 242 | |
| 243 | for (c = 0; c < src->num_auths; c++) { |
| 244 | dst->sub_auths[c] = src->sub_auths[c]; |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | static bool_Bool sid_compose(struct dom_sid *dst, const struct dom_sid *dom_sid, |
| 249 | uint32_t rid) |
| 250 | { |
| 251 | if (dom_sid->num_auths >= 15) { |
| 252 | return false0; |
| 253 | } |
| 254 | |
| 255 | sid_copy(dst, dom_sid); |
| 256 | |
| 257 | dst->sub_auths[dst->num_auths++] = rid; |
| 258 | |
| 259 | return true1; |
| 260 | } |
| 261 | |
| 262 | static char *sid_talloc_string(struct sss_idmap_ctx *ctx, void *final_ctx, const struct dom_sid *dom_sid) |
| 263 | { |
| 264 | enum idmap_error_code ret; |
| 265 | char *result = NULL((void*)0); |
| 266 | ret = sss_idmap_smb_sid_to_sid(ctx, discard_const(dom_sid)((void *)((uintptr_t)(dom_sid))), &result); |
| 267 | if (ret != IDMAP_SUCCESS) { |
| 268 | return NULL((void*)0); |
| 269 | } |
| 270 | |
| 271 | return talloc_move(final_ctx, &result)(__typeof__(*(&result)))_talloc_move((final_ctx),(void *) (&result)); |
| 272 | } |
| 273 | |
| 274 | static bool_Bool is_null_sid(const struct dom_sid *sid) |
| 275 | { |
| 276 | size_t c; |
| 277 | |
| 278 | if (sid->sid_rev_num != 0 || sid->num_auths != 0) { |
| 279 | return false0; |
| 280 | } |
| 281 | |
| 282 | for (c = 0; c < 6; c++) { |
| 283 | if (sid->id_auth[c] != 0) { |
| 284 | return false0; |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | for (c = 0; c < 15; c++) { |
| 289 | if (sid->sub_auths[c] != 0) { |
| 290 | return false0; |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | return true1; |
| 295 | } |
| 296 | |
| 297 | static int dom_sid_compare_domain(const struct dom_sid *sid1, |
| 298 | const struct dom_sid *sid2) |
| 299 | { |
| 300 | size_t c; |
| 301 | size_t n_sub_auths; |
| 302 | |
| 303 | if (sid1->sid_rev_num != sid2->sid_rev_num) { |
| 304 | return sid1->sid_rev_num - sid2->sid_rev_num; |
| 305 | } |
| 306 | |
| 307 | for (c = 0; c < 6; c++) { |
| 308 | if (sid1->id_auth[c] != sid2->id_auth[c]) { |
| 309 | return sid1->id_auth[c] - sid2->id_auth[c]; |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | n_sub_auths = (sid1->num_auths < sid2->num_auths) ? sid1->num_auths : |
| 314 | sid2->num_auths; |
| 315 | |
| 316 | for (c = 0; c < n_sub_auths; c++) { |
| 317 | if (sid1->sub_auths[c] != sid2->sub_auths[c]) { |
| 318 | return sid1->sub_auths[c] - sid2->sub_auths[c]; |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | return 0; |
| 323 | } |
| 324 | |
| 325 | static bool_Bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, |
| 326 | const struct dom_sid *sid, uint32_t *rid) |
| 327 | { |
| 328 | if((exp_dom_sid->num_auths + 1) != sid->num_auths || |
| 329 | sid->num_auths <= 0) { |
| 330 | return false0; |
| 331 | } |
| 332 | |
| 333 | if (dom_sid_compare_domain(exp_dom_sid, sid) != 0) { |
| 334 | return false0; |
| 335 | } |
| 336 | |
| 337 | *rid = sid->sub_auths[sid->num_auths - 1]; |
| 338 | |
| 339 | return true1; |
| 340 | } |
| 341 | |
| 342 | static bool_Bool strnequal(const char *s1, const char *s2, size_t n) { |
| 343 | if (s1 == s2) { |
| 344 | return true1; |
| 345 | } |
| 346 | |
| 347 | if (s1 == NULL((void*)0) || s2 == NULL((void*)0) || n == 0) { |
| 348 | return false0; |
| 349 | } |
| 350 | |
| 351 | if (strncasecmp(s1, s2, n) == 0) { |
| 352 | return true1; |
| 353 | } |
| 354 | |
| 355 | return false0; |
| 356 | } |
| 357 | |
| 358 | static LDAP *_smbldap_get_ldap(struct smbldap_state *state) { |
| 359 | #ifdef HAVE_SMBLDAP_GET_LDAP1 |
| 360 | return smbldap_get_ldap(state); |
| 361 | #else |
| 362 | return state->ldap_struct; |
| 363 | #endif |
| 364 | |
| 365 | } |
| 366 | |
| 367 | static bool_Bool _smbldap_get_paged_results(struct smbldap_state *state) { |
| 368 | #ifdef HAVE_SMBLDAP_GET_LDAP1 |
| 369 | return smbldap_get_paged_results(state); |
| 370 | #else |
| 371 | return state->paged_results; |
| 372 | #endif |
| 373 | } |
| 374 | |
| 375 | static void _smbldap_set_paged_results(struct smbldap_state *state, |
| 376 | bool_Bool paged_results) { |
| 377 | #ifdef HAVE_SMBLDAP_GET_LDAP1 |
| 378 | smbldap_set_paged_results(state, paged_results); |
| 379 | #else |
| 380 | state->paged_results = paged_results; |
| 381 | #endif |
| 382 | } |
| 383 | |
| 384 | static LDAP *priv2ld(struct ipasam_private *priv) |
| 385 | { |
| 386 | return _smbldap_get_ldap(priv->ldap_state); |
| 387 | } |
| 388 | |
| 389 | /* |
| 390 | * get_attribute_values() returns array of all values of the attribute |
| 391 | * allocated over mem_ctx |
| 392 | */ |
| 393 | static char **get_attribute_values(TALLOC_CTX *mem_ctx, LDAP *ldap_struct, |
| 394 | LDAPMessage *entry, const char *attribute, int *num_values) |
| 395 | { |
| 396 | struct berval **values; |
| 397 | int count, i; |
| 398 | char **result = NULL((void*)0); |
| 399 | size_t conv_size; |
| 400 | |
| 401 | if (attribute == NULL((void*)0) || entry == NULL((void*)0)) { |
| 402 | return NULL((void*)0); |
| 403 | } |
| 404 | |
| 405 | values = ldap_get_values_len(ldap_struct, entry, attribute); |
| 406 | if (values == NULL((void*)0)) { |
| 407 | DEBUG(10, ("Attribute [%s] not found.\n", attribute))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "407" , __FUNCTION__ )) && (dbgtext ("Attribute [%s] not found.\n" , attribute)) ); |
| 408 | return NULL((void*)0); |
| 409 | } |
| 410 | |
| 411 | count = ldap_count_values_len(values); |
| 412 | if (count == 0) { |
| 413 | goto done; |
| 414 | } |
| 415 | |
| 416 | result = talloc_array(mem_ctx, char *, count)(char * *)_talloc_array(mem_ctx, sizeof(char *), count, "char *" ); |
| 417 | if (result == NULL((void*)0)) { |
| 418 | goto done; |
| 419 | } |
| 420 | |
| 421 | *num_values = count; |
| 422 | for (i = 0; i < count; i++) { |
| 423 | if (!convert_string_talloc(result, CH_UTF8, CH_UNIX, |
| 424 | values[i]->bv_val, values[i]->bv_len, |
| 425 | &result[i], &conv_size)) { |
| 426 | DEBUG(10, ("Failed to convert %dth value of [%s] out of %d.\n",(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "427" , __FUNCTION__ )) && (dbgtext ("Failed to convert %dth value of [%s] out of %d.\n" , i, attribute, count)) ) |
| 427 | i, attribute, count))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "427" , __FUNCTION__ )) && (dbgtext ("Failed to convert %dth value of [%s] out of %d.\n" , i, attribute, count)) ); |
| 428 | talloc_free(result)_talloc_free(result, "ipa_sam.c" ":" "428"); |
| 429 | result = NULL((void*)0); |
| 430 | goto done; |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | done: |
| 435 | ldap_value_free_len(values); |
| 436 | return result; |
| 437 | } |
| 438 | |
| 439 | static char *get_single_attribute(TALLOC_CTX *mem_ctx, LDAP *ldap_struct, |
| 440 | LDAPMessage *entry, const char *attribute) |
| 441 | { |
| 442 | struct berval **values; |
| 443 | int c; |
| 444 | char *result = NULL((void*)0); |
| 445 | size_t conv_size; |
| 446 | |
| 447 | if (attribute == NULL((void*)0) || entry == NULL((void*)0)) { |
| 448 | return NULL((void*)0); |
| 449 | } |
| 450 | |
| 451 | values = ldap_get_values_len(ldap_struct, entry, attribute); |
| 452 | if (values == NULL((void*)0)) { |
| 453 | DEBUG(10, ("Attribute [%s] not found.\n", attribute))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "453" , __FUNCTION__ )) && (dbgtext ("Attribute [%s] not found.\n" , attribute)) ); |
| 454 | return NULL((void*)0); |
| 455 | } |
| 456 | |
| 457 | c = ldap_count_values_len(values); |
| 458 | if (c != 1) { |
| 459 | DEBUG(10, ("Found [%d] values for attribute [%s] but expected only 1.\n",(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "460" , __FUNCTION__ )) && (dbgtext ("Found [%d] values for attribute [%s] but expected only 1.\n" , c, attribute)) ) |
| 460 | c, attribute))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "460" , __FUNCTION__ )) && (dbgtext ("Found [%d] values for attribute [%s] but expected only 1.\n" , c, attribute)) ); |
| 461 | goto done; |
| 462 | } |
| 463 | |
| 464 | if (!convert_string_talloc(mem_ctx, CH_UTF8, CH_UNIX, |
| 465 | values[0]->bv_val, values[0]->bv_len, |
| 466 | &result, &conv_size)) { |
| 467 | DEBUG(10, ("Failed to convert value of [%s].\n", attribute))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "467" , __FUNCTION__ )) && (dbgtext ("Failed to convert value of [%s].\n" , attribute)) ); |
| 468 | result = NULL((void*)0); |
| 469 | goto done; |
| 470 | } |
| 471 | |
| 472 | done: |
| 473 | ldap_value_free_len(values); |
| 474 | return result; |
| 475 | } |
| 476 | |
| 477 | static char *get_dn(TALLOC_CTX *mem_ctx, LDAP *ld, LDAPMessage *entry) |
| 478 | { |
| 479 | char *utf8_dn; |
| 480 | char *unix_dn = NULL((void*)0); |
| 481 | size_t conv_size; |
| 482 | |
| 483 | utf8_dn = ldap_get_dn(ld, entry); |
| 484 | if (utf8_dn == NULL((void*)0)) { |
| 485 | DEBUG (10, ("ldap_get_dn failed\n"))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "485" , __FUNCTION__ )) && (dbgtext ("ldap_get_dn failed\n" )) ); |
| 486 | return NULL((void*)0); |
| 487 | } |
| 488 | if (!convert_string_talloc(mem_ctx, CH_UTF8, CH_UNIX, |
| 489 | utf8_dn, strlen(utf8_dn) + 1, |
| 490 | &unix_dn, &conv_size)) { |
| 491 | DEBUG (10, ("Failed to convert [%s]\n", utf8_dn))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "491" , __FUNCTION__ )) && (dbgtext ("Failed to convert [%s]\n" , utf8_dn)) ); |
| 492 | unix_dn = NULL((void*)0); |
| 493 | goto done; |
| 494 | } |
| 495 | |
| 496 | done: |
| 497 | ldap_memfree(utf8_dn); |
| 498 | return unix_dn; |
| 499 | } |
| 500 | |
| 501 | /* Samba removed unixid_* helpers in c906153cc7af21abe508ddd30c447642327d6a5d */ |
| 502 | static void ipasam_unixid_from_uid(struct unixid *id, uint32_t some_uid) |
| 503 | { |
| 504 | if (id) { |
| 505 | id->id = some_uid; |
| 506 | id->type = ID_TYPE_UID; |
| 507 | } |
| 508 | } |
| 509 | |
| 510 | |
| 511 | |
| 512 | static void ipasam_unixid_from_gid(struct unixid *id, uint32_t some_gid) |
| 513 | { |
| 514 | if (id) { |
| 515 | id->id = some_gid; |
| 516 | id->type = ID_TYPE_GID; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | static bool_Bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct, |
| 521 | LDAPMessage *entry, |
| 522 | struct sss_idmap_ctx *idmap_ctx, |
| 523 | const struct dom_sid *domain_sid, |
| 524 | uint32_t *rid) |
| 525 | { |
| 526 | char *str = NULL((void*)0); |
| 527 | struct dom_sid *sid = NULL((void*)0); |
| 528 | bool_Bool res = false0; |
| 529 | enum idmap_error_code err; |
| 530 | |
| 531 | str = get_single_attribute(NULL((void*)0), ldap_struct, entry, |
| 532 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 533 | if (str == NULL((void*)0)) { |
| 534 | DEBUG(10, ("Could not find SID attribute\n"))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "534" , __FUNCTION__ )) && (dbgtext ("Could not find SID attribute\n" )) ); |
| 535 | res = false0; |
| 536 | goto done; |
| 537 | } |
| 538 | |
| 539 | err = sss_idmap_sid_to_smb_sid(idmap_ctx, str, &sid); |
| 540 | if (err != IDMAP_SUCCESS) { |
| 541 | DEBUG(10, ("Could not convert string %s to sid\n", str))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "541" , __FUNCTION__ )) && (dbgtext ("Could not convert string %s to sid\n" , str)) ); |
| 542 | res = false0; |
| 543 | goto done; |
| 544 | } |
| 545 | |
| 546 | if (dom_sid_compare_domain(sid, domain_sid) != 0) { |
| 547 | char *debug_domain_sid = NULL((void*)0); |
| 548 | err = sss_idmap_smb_sid_to_sid(idmap_ctx, |
| 549 | discard_const(domain_sid)((void *)((uintptr_t)(domain_sid))), |
| 550 | &debug_domain_sid); |
| 551 | if (err != IDMAP_SUCCESS) { |
| 552 | DEBUG(10, ("SID %s is not in expected domain.\n",(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "553" , __FUNCTION__ )) && (dbgtext ("SID %s is not in expected domain.\n" , str)) ) |
| 553 | str))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "553" , __FUNCTION__ )) && (dbgtext ("SID %s is not in expected domain.\n" , str)) ); |
| 554 | } else { |
| 555 | DEBUG(10, ("SID %s is not in expected domain %s\n",(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "556" , __FUNCTION__ )) && (dbgtext ("SID %s is not in expected domain %s\n" , str, debug_domain_sid)) ) |
| 556 | str, debug_domain_sid))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "556" , __FUNCTION__ )) && (dbgtext ("SID %s is not in expected domain %s\n" , str, debug_domain_sid)) ); |
| 557 | talloc_free(debug_domain_sid)_talloc_free(debug_domain_sid, "ipa_sam.c" ":" "557"); |
| 558 | } |
| 559 | res = false0; |
| 560 | goto done; |
| 561 | } |
| 562 | |
| 563 | if (sid->num_auths <= 0) { |
| 564 | DEBUG(10, ("Invalid num_auths in SID %s.\n", str))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "564" , __FUNCTION__ )) && (dbgtext ("Invalid num_auths in SID %s.\n" , str)) ); |
| 565 | res = false0; |
| 566 | goto done; |
| 567 | } |
| 568 | |
| 569 | *rid = sid->sub_auths[sid->num_auths - 1]; |
| 570 | |
| 571 | res = true1; |
| 572 | done: |
| 573 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "573"); |
| 574 | talloc_free(str)_talloc_free(str, "ipa_sam.c" ":" "574"); |
| 575 | return res; |
| 576 | } |
| 577 | |
| 578 | static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods, |
| 579 | const struct dom_sid *domain_sid, |
| 580 | int num_rids, |
| 581 | uint32_t *rids, |
| 582 | const char **names, |
| 583 | enum lsa_SidType *attrs) |
| 584 | { |
| 585 | struct ipasam_private *ipasam_state = |
| 586 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "586"); |
| 587 | LDAPMessage *msg = NULL((void*)0); |
| 588 | LDAPMessage *entry; |
| 589 | char *allsids = NULL((void*)0); |
| 590 | int i, rc, num_mapped; |
| 591 | NTSTATUS result = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 592 | TALLOC_CTX *mem_ctx; |
| 593 | LDAP *ld; |
| 594 | bool_Bool is_builtin; |
| 595 | |
| 596 | mem_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "596"); |
| 597 | if (mem_ctx == NULL((void*)0)) { |
| 598 | DEBUG(0, ("talloc_new failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "598", __FUNCTION__ )) && (dbgtext ("talloc_new failed\n")) ); |
| 599 | goto done; |
| 600 | } |
| 601 | |
| 602 | if (!sid_check_is_builtin(domain_sid) && |
| 603 | dom_sid_compare_domain(&ipasam_state->domain_sid, domain_sid) != 0) { |
| 604 | result = NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 605 | goto done; |
| 606 | } |
| 607 | |
| 608 | if (num_rids == 0) { |
| 609 | result = NT_STATUS_NONE_MAPPED((NTSTATUS) { 0xc0000073 }); |
| 610 | goto done; |
| 611 | } |
| 612 | |
| 613 | for (i=0; i<num_rids; i++) |
| 614 | attrs[i] = SID_NAME_UNKNOWN; |
| 615 | |
| 616 | allsids = talloc_strdup(mem_ctx, ""); |
| 617 | if (allsids == NULL((void*)0)) { |
| 618 | goto done; |
| 619 | } |
| 620 | |
| 621 | for (i=0; i<num_rids; i++) { |
| 622 | struct dom_sid sid; |
| 623 | sid_compose(&sid, domain_sid, rids[i]); |
| 624 | allsids = talloc_asprintf_append_buffer( |
| 625 | allsids, "(%s=%s)", |
| 626 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 627 | sid_talloc_string(ipasam_state->idmap_ctx, mem_ctx, &sid)); |
| 628 | if (allsids == NULL((void*)0)) { |
| 629 | goto done; |
| 630 | } |
| 631 | } |
| 632 | |
| 633 | /* First look for users */ |
| 634 | |
| 635 | { |
| 636 | char *filter; |
| 637 | const char *ldap_attrs[] = { "uid", LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", NULL((void*)0) }; |
| 638 | |
| 639 | filter = talloc_asprintf( |
| 640 | mem_ctx, ("(&(objectClass=%s)(|%s))"), |
| 641 | LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs", allsids); |
| 642 | |
| 643 | if (filter == NULL((void*)0)) { |
| 644 | goto done; |
| 645 | } |
| 646 | |
| 647 | rc = smbldap_search(ipasam_state->ldap_state, |
| 648 | ipasam_state->base_dn, |
| 649 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), filter, ldap_attrs, 0, |
| 650 | &msg); |
| 651 | smbldap_talloc_autofree_ldapmsg(mem_ctx, msg); |
| 652 | } |
| 653 | |
| 654 | if (rc != LDAP_SUCCESS0x00) |
| 655 | goto done; |
| 656 | |
| 657 | ld = priv2ld(ipasam_state); |
| 658 | num_mapped = 0; |
| 659 | |
| 660 | for (entry = ldap_first_entry(ld, msg); |
| 661 | entry != NULL((void*)0); |
| 662 | entry = ldap_next_entry(ld, entry)) { |
| 663 | uint32_t rid; |
| 664 | int rid_index; |
| 665 | const char *name; |
| 666 | |
| 667 | if (!ldapsam_extract_rid_from_entry(ld, entry, |
| 668 | ipasam_state->idmap_ctx, |
| 669 | domain_sid, |
| 670 | &rid)) { |
| 671 | DEBUG(2, ("Could not find sid from ldap entry\n"))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "671", __FUNCTION__ )) && (dbgtext ("Could not find sid from ldap entry\n" )) ); |
| 672 | continue; |
| 673 | } |
| 674 | |
| 675 | name = get_single_attribute(names, ld, entry, "uid"); |
| 676 | if (name == NULL((void*)0)) { |
| 677 | DEBUG(2, ("Could not retrieve uid attribute\n"))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "677", __FUNCTION__ )) && (dbgtext ("Could not retrieve uid attribute\n" )) ); |
| 678 | continue; |
| 679 | } |
| 680 | |
| 681 | for (rid_index = 0; rid_index < num_rids; rid_index++) { |
| 682 | if (rid == rids[rid_index]) |
| 683 | break; |
| 684 | } |
| 685 | |
| 686 | if (rid_index == num_rids) { |
| 687 | DEBUG(2, ("Got a RID not asked for: %d\n", rid))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "687", __FUNCTION__ )) && (dbgtext ("Got a RID not asked for: %d\n", rid )) ); |
| 688 | continue; |
| 689 | } |
| 690 | |
| 691 | attrs[rid_index] = SID_NAME_USER; |
| 692 | names[rid_index] = name; |
| 693 | num_mapped += 1; |
| 694 | } |
| 695 | |
| 696 | if (num_mapped == num_rids) { |
| 697 | /* No need to look for groups anymore -- we're done */ |
| 698 | result = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 699 | goto done; |
| 700 | } |
| 701 | |
| 702 | /* Same game for groups */ |
| 703 | |
| 704 | { |
| 705 | char *filter; |
| 706 | const char *ldap_attrs[] = { "cn", "displayName", |
| 707 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 708 | NULL((void*)0) }; |
| 709 | |
| 710 | filter = talloc_asprintf( |
| 711 | mem_ctx, "(&(objectClass=%s)(|%s))", |
| 712 | LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs", allsids); |
| 713 | if (filter == NULL((void*)0)) { |
| 714 | goto done; |
| 715 | } |
| 716 | |
| 717 | rc = smbldap_search(ipasam_state->ldap_state, |
| 718 | ipasam_state->base_dn, |
| 719 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), filter, ldap_attrs, 0, |
| 720 | &msg); |
| 721 | smbldap_talloc_autofree_ldapmsg(mem_ctx, msg); |
| 722 | } |
| 723 | |
| 724 | if (rc != LDAP_SUCCESS0x00) |
| 725 | goto done; |
| 726 | |
| 727 | /* ldap_struct might have changed due to a reconnect */ |
| 728 | |
| 729 | ld = priv2ld(ipasam_state); |
| 730 | |
| 731 | /* For consistency checks, we already checked we're only domain or builtin */ |
| 732 | |
| 733 | is_builtin = sid_check_is_builtin(domain_sid); |
| 734 | |
| 735 | for (entry = ldap_first_entry(ld, msg); |
| 736 | entry != NULL((void*)0); |
| 737 | entry = ldap_next_entry(ld, entry)) |
| 738 | { |
| 739 | uint32_t rid; |
| 740 | int rid_index; |
| 741 | const char *attr; |
| 742 | enum lsa_SidType type; |
| 743 | const char *dn = get_dn(mem_ctx, ld, entry); |
| 744 | |
| 745 | type = SID_NAME_DOM_GRP; |
| 746 | |
| 747 | /* Consistency checks */ |
| 748 | if ((is_builtin && (type != SID_NAME_ALIAS)) || |
| 749 | (!is_builtin && ((type != SID_NAME_ALIAS) && |
| 750 | (type != SID_NAME_DOM_GRP)))) { |
| 751 | DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "751", __FUNCTION__ )) && (dbgtext ("Rejecting invalid group mapping entry %s\n" , dn)) ); |
| 752 | } |
| 753 | |
| 754 | if (!ldapsam_extract_rid_from_entry(ld, entry, |
| 755 | ipasam_state->idmap_ctx, |
| 756 | domain_sid, &rid)) { |
| 757 | DEBUG(2, ("Could not find sid from ldap entry %s\n", dn))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "757", __FUNCTION__ )) && (dbgtext ("Could not find sid from ldap entry %s\n" , dn)) ); |
| 758 | continue; |
| 759 | } |
| 760 | |
| 761 | attr = get_single_attribute(names, ld, entry, "displayName"); |
| 762 | |
| 763 | if (attr == NULL((void*)0)) { |
| 764 | DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "765" , __FUNCTION__ )) && (dbgtext ("Could not retrieve 'displayName' attribute from %s\n" , dn)) ) |
| 765 | dn))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "765" , __FUNCTION__ )) && (dbgtext ("Could not retrieve 'displayName' attribute from %s\n" , dn)) ); |
| 766 | attr = get_single_attribute(names, ld, entry, "cn"); |
| 767 | } |
| 768 | |
| 769 | if (attr == NULL((void*)0)) { |
| 770 | DEBUG(2, ("Could not retrieve naming attribute from %s\n",(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "771", __FUNCTION__ )) && (dbgtext ("Could not retrieve naming attribute from %s\n" , dn)) ) |
| 771 | dn))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "771", __FUNCTION__ )) && (dbgtext ("Could not retrieve naming attribute from %s\n" , dn)) ); |
| 772 | continue; |
| 773 | } |
| 774 | |
| 775 | for (rid_index = 0; rid_index < num_rids; rid_index++) { |
| 776 | if (rid == rids[rid_index]) |
| 777 | break; |
| 778 | } |
| 779 | |
| 780 | if (rid_index == num_rids) { |
| 781 | DEBUG(2, ("Got a RID not asked for: %d\n", rid))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "781", __FUNCTION__ )) && (dbgtext ("Got a RID not asked for: %d\n", rid )) ); |
| 782 | continue; |
| 783 | } |
| 784 | |
| 785 | attrs[rid_index] = type; |
| 786 | names[rid_index] = attr; |
| 787 | num_mapped += 1; |
| 788 | } |
| 789 | |
| 790 | result = NT_STATUS_NONE_MAPPED((NTSTATUS) { 0xc0000073 }); |
| 791 | |
| 792 | if (num_mapped > 0) |
| 793 | result = (num_mapped == num_rids) ? |
| 794 | NT_STATUS_OK((NTSTATUS) { 0x0 }) : STATUS_SOME_UNMAPPED((NTSTATUS) { 0x107 }); |
| 795 | done: |
| 796 | TALLOC_FREE(mem_ctx)do { if (mem_ctx != ((void*)0)) { _talloc_free(mem_ctx, "ipa_sam.c" ":" "796"); mem_ctx=((void*)0); } } while(0); |
| 797 | return result; |
| 798 | } |
| 799 | |
| 800 | static bool_Bool ldapsam_sid_to_id(struct pdb_methods *methods, |
| 801 | const struct dom_sid *sid, |
| 802 | struct unixid *id) |
| 803 | { |
| 804 | struct ipasam_private *priv = |
| 805 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "805"); |
| 806 | char *filter; |
| 807 | const char *attrs[] = { "objectClass", "gidNumber", "uidNumber", |
| 808 | NULL((void*)0) }; |
| 809 | LDAPMessage *result = NULL((void*)0); |
| 810 | LDAPMessage *entry = NULL((void*)0); |
| 811 | bool_Bool ret = false0; |
| 812 | char *value; |
| 813 | struct berval **values; |
| 814 | size_t c; |
| 815 | int rc; |
| 816 | |
| 817 | TALLOC_CTX *mem_ctx; |
| 818 | |
| 819 | mem_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "819"); |
| 820 | if (mem_ctx == NULL((void*)0)) { |
| 821 | DEBUG(0, ("talloc_new failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "821", __FUNCTION__ )) && (dbgtext ("talloc_new failed\n")) ); |
| 822 | return false0; |
| 823 | } |
| 824 | |
| 825 | filter = talloc_asprintf(mem_ctx, |
| 826 | "(&(%s=%s)" |
| 827 | "(|(objectClass=%s)(objectClass=%s)))", |
| 828 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 829 | sid_talloc_string(priv->idmap_ctx, mem_ctx, sid), |
| 830 | LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs", LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs"); |
| 831 | if (filter == NULL((void*)0)) { |
| 832 | DEBUG(5, ("talloc_asprintf failed\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "832", __FUNCTION__ )) && (dbgtext ("talloc_asprintf failed\n")) ); |
| 833 | goto done; |
| 834 | } |
| 835 | |
| 836 | rc = smbldap_search_suffix(priv->ldap_state, filter, |
| 837 | attrs, &result); |
| 838 | if (rc != LDAP_SUCCESS0x00) { |
| 839 | goto done; |
| 840 | } |
| 841 | smbldap_talloc_autofree_ldapmsg(mem_ctx, result); |
| 842 | |
| 843 | if (ldap_count_entries(priv2ld(priv), result) != 1) { |
| 844 | DEBUG(10, ("Got %d entries, expected one\n",(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "845" , __FUNCTION__ )) && (dbgtext ("Got %d entries, expected one\n" , ldap_count_entries(priv2ld(priv), result))) ) |
| 845 | ldap_count_entries(priv2ld(priv), result)))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "845" , __FUNCTION__ )) && (dbgtext ("Got %d entries, expected one\n" , ldap_count_entries(priv2ld(priv), result))) ); |
| 846 | goto done; |
| 847 | } |
| 848 | |
| 849 | entry = ldap_first_entry(priv2ld(priv), result); |
| 850 | |
| 851 | values = ldap_get_values_len(priv2ld(priv), entry, "objectClass"); |
| 852 | if (values == NULL((void*)0)) { |
| 853 | DEBUG(10, ("Cannot find any objectclasses.\n"))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "853" , __FUNCTION__ )) && (dbgtext ("Cannot find any objectclasses.\n" )) ); |
| 854 | goto done; |
| 855 | } |
| 856 | |
| 857 | for (c = 0; values[c] != NULL((void*)0); c++) { |
| 858 | if (strncasecmp(LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs", values[c]->bv_val, |
| 859 | values[c]->bv_len) == 0) { |
| 860 | break; |
| 861 | } |
| 862 | } |
| 863 | |
| 864 | if (values[c] != NULL((void*)0)) { |
| 865 | const char *gid_str; |
| 866 | /* It's a group */ |
| 867 | |
| 868 | gid_str = get_single_attribute(mem_ctx, priv2ld(priv), entry, |
| 869 | "gidNumber"); |
| 870 | if (gid_str == NULL((void*)0)) { |
| 871 | DEBUG(1, ("%s has no gidNumber\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "872", __FUNCTION__ )) && (dbgtext ("%s has no gidNumber\n", get_dn(mem_ctx , priv2ld(priv), entry))) ) |
| 872 | get_dn(mem_ctx, priv2ld(priv), entry)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "872", __FUNCTION__ )) && (dbgtext ("%s has no gidNumber\n", get_dn(mem_ctx , priv2ld(priv), entry))) ); |
| 873 | goto done; |
| 874 | } |
| 875 | |
| 876 | ipasam_unixid_from_gid(id, strtoul(gid_str, NULL((void*)0), 10)); |
| 877 | |
| 878 | idmap_cache_set_sid2unixid(sid, id); |
| 879 | |
| 880 | ret = true1; |
| 881 | goto done; |
| 882 | } |
| 883 | |
| 884 | /* It must be a user */ |
| 885 | |
| 886 | value = get_single_attribute(mem_ctx, priv2ld(priv), entry, |
| 887 | "uidNumber"); |
| 888 | if (value == NULL((void*)0)) { |
| 889 | DEBUG(1, ("Could not find uidNumber in %s\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "890", __FUNCTION__ )) && (dbgtext ("Could not find uidNumber in %s\n", get_dn (mem_ctx, priv2ld(priv), entry))) ) |
| 890 | get_dn(mem_ctx, priv2ld(priv), entry)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "890", __FUNCTION__ )) && (dbgtext ("Could not find uidNumber in %s\n", get_dn (mem_ctx, priv2ld(priv), entry))) ); |
| 891 | goto done; |
| 892 | } |
| 893 | |
| 894 | ipasam_unixid_from_uid(id, strtoul(value, NULL((void*)0), 10)); |
| 895 | |
| 896 | idmap_cache_set_sid2unixid(sid, id); |
| 897 | |
| 898 | ret = true1; |
| 899 | done: |
| 900 | |
| 901 | TALLOC_FREE(mem_ctx)do { if (mem_ctx != ((void*)0)) { _talloc_free(mem_ctx, "ipa_sam.c" ":" "901"); mem_ctx=((void*)0); } } while(0); |
| 902 | return ret; |
| 903 | } |
| 904 | |
| 905 | static bool_Bool ipasam_uid_to_sid(struct pdb_methods *methods, uid_t uid, |
| 906 | struct dom_sid *sid) |
| 907 | { |
| 908 | struct ipasam_private *priv = |
| 909 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "909"); |
| 910 | char *filter; |
| 911 | const char *attrs[] = { LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", NULL((void*)0) }; |
| 912 | LDAPMessage *result = NULL((void*)0); |
| 913 | LDAPMessage *entry = NULL((void*)0); |
| 914 | bool_Bool ret = false0; |
| 915 | char *user_sid_string; |
| 916 | struct dom_sid *user_sid = NULL((void*)0); |
| 917 | int rc; |
| 918 | enum idmap_error_code err; |
| 919 | struct unixid id; |
| 920 | |
| 921 | TALLOC_CTX *tmp_ctx = talloc_new(priv)talloc_named_const(priv, 0, "talloc_new: " "ipa_sam.c" ":" "921" ); |
| 922 | if (tmp_ctx == NULL((void*)0)) { |
| 923 | goto done; |
| 924 | } |
| 925 | |
| 926 | /* Fast fail if we get a request for uidNumber=0 because it currently |
| 927 | * will never exist in the directory |
| 928 | * Saves an expensive LDAP call of which failure will never be cached |
| 929 | */ |
| 930 | if (uid == 0) { |
| 931 | DEBUG(3, ("ERROR: Received request for uid %u, "(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "933", __FUNCTION__ )) && (dbgtext ("ERROR: Received request for uid %u, " "fast failing as it will never exist\n", (unsigned int)uid)) ) |
| 932 | "fast failing as it will never exist\n",(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "933", __FUNCTION__ )) && (dbgtext ("ERROR: Received request for uid %u, " "fast failing as it will never exist\n", (unsigned int)uid)) ) |
| 933 | (unsigned int)uid))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "933", __FUNCTION__ )) && (dbgtext ("ERROR: Received request for uid %u, " "fast failing as it will never exist\n", (unsigned int)uid)) ); |
| 934 | goto done; |
| 935 | } |
| 936 | |
| 937 | filter = talloc_asprintf(tmp_ctx, |
| 938 | "(&(uidNumber=%u)" |
| 939 | "(objectClass=%s)" |
| 940 | "(objectClass=%s))", |
| 941 | (unsigned int)uid, |
| 942 | LDAP_OBJ_POSIXACCOUNT"posixAccount", |
| 943 | LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs"); |
| 944 | if (filter == NULL((void*)0)) { |
| 945 | DEBUG(3, ("talloc_asprintf failed\n"))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "945", __FUNCTION__ )) && (dbgtext ("talloc_asprintf failed\n")) ); |
| 946 | goto done; |
| 947 | } |
| 948 | |
| 949 | rc = smbldap_search_suffix(priv->ldap_state, filter, attrs, &result); |
| 950 | if (rc != LDAP_SUCCESS0x00) { |
| 951 | goto done; |
| 952 | } |
| 953 | smbldap_talloc_autofree_ldapmsg(tmp_ctx, result); |
| 954 | |
| 955 | if (ldap_count_entries(priv2ld(priv), result) != 1) { |
| 956 | DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "958", __FUNCTION__ )) && (dbgtext ("ERROR: Got %d entries for uid %u, expected one\n" , ldap_count_entries(priv2ld(priv), result), (unsigned int)uid )) ) |
| 957 | ldap_count_entries(priv2ld(priv), result),(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "958", __FUNCTION__ )) && (dbgtext ("ERROR: Got %d entries for uid %u, expected one\n" , ldap_count_entries(priv2ld(priv), result), (unsigned int)uid )) ) |
| 958 | (unsigned int)uid))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "958", __FUNCTION__ )) && (dbgtext ("ERROR: Got %d entries for uid %u, expected one\n" , ldap_count_entries(priv2ld(priv), result), (unsigned int)uid )) ); |
| 959 | goto done; |
| 960 | } |
| 961 | |
| 962 | entry = ldap_first_entry(priv2ld(priv), result); |
| 963 | |
| 964 | user_sid_string = get_single_attribute(tmp_ctx, priv2ld(priv), entry, |
| 965 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 966 | if (user_sid_string == NULL((void*)0)) { |
| 967 | DEBUG(1, ("Could not find SID in object '%s'\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "968", __FUNCTION__ )) && (dbgtext ("Could not find SID in object '%s'\n" , get_dn(tmp_ctx, priv2ld(priv), entry))) ) |
| 968 | get_dn(tmp_ctx, priv2ld(priv), entry)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "968", __FUNCTION__ )) && (dbgtext ("Could not find SID in object '%s'\n" , get_dn(tmp_ctx, priv2ld(priv), entry))) ); |
| 969 | goto done; |
| 970 | } |
| 971 | |
| 972 | err = sss_idmap_sid_to_smb_sid(priv->idmap_ctx, |
| 973 | user_sid_string, &user_sid); |
| 974 | if (err != IDMAP_SUCCESS) { |
| 975 | DEBUG(3, ("Error creating sid structure for sid '%s'\n",(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "976", __FUNCTION__ )) && (dbgtext ("Error creating sid structure for sid '%s'\n" , user_sid_string)) ) |
| 976 | user_sid_string))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "976", __FUNCTION__ )) && (dbgtext ("Error creating sid structure for sid '%s'\n" , user_sid_string)) ); |
| 977 | goto done; |
| 978 | } |
| 979 | |
| 980 | sid_copy(sid, user_sid); |
| 981 | |
| 982 | ipasam_unixid_from_uid(&id, uid); |
| 983 | |
| 984 | idmap_cache_set_sid2unixid(sid, &id); |
| 985 | |
| 986 | ret = true1; |
| 987 | |
| 988 | done: |
| 989 | talloc_free(user_sid)_talloc_free(user_sid, "ipa_sam.c" ":" "989"); |
| 990 | TALLOC_FREE(tmp_ctx)do { if (tmp_ctx != ((void*)0)) { _talloc_free(tmp_ctx, "ipa_sam.c" ":" "990"); tmp_ctx=((void*)0); } } while(0); |
| 991 | return ret; |
| 992 | } |
| 993 | |
| 994 | static bool_Bool ipasam_gid_to_sid(struct pdb_methods *methods, gid_t gid, |
| 995 | struct dom_sid *sid) |
| 996 | { |
| 997 | struct ipasam_private *priv = |
| 998 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "998"); |
| 999 | char *filter; |
| 1000 | const char *attrs[] = { LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", NULL((void*)0) }; |
| 1001 | LDAPMessage *result = NULL((void*)0); |
| 1002 | LDAPMessage *entry = NULL((void*)0); |
| 1003 | bool_Bool ret = false0; |
| 1004 | char *group_sid_string = NULL((void*)0); |
| 1005 | struct dom_sid *group_sid = NULL((void*)0); |
| 1006 | struct berval **values; |
| 1007 | size_t c; |
| 1008 | int rc; |
| 1009 | enum idmap_error_code err; |
| 1010 | struct unixid id; |
| 1011 | |
| 1012 | TALLOC_CTX *tmp_ctx = talloc_new(priv)talloc_named_const(priv, 0, "talloc_new: " "ipa_sam.c" ":" "1012" ); |
| 1013 | if (tmp_ctx == NULL((void*)0)) { |
| 1014 | goto done; |
| 1015 | } |
| 1016 | |
| 1017 | filter = talloc_asprintf(tmp_ctx, |
| 1018 | "(|(&(gidNumber=%u)" |
| 1019 | "(objectClass=%s))" |
| 1020 | "(&(uidNumber=%u)" |
| 1021 | "(objectClass=%s)" |
| 1022 | "(objectClass=%s)))", |
| 1023 | (unsigned int)gid, |
| 1024 | LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs", |
| 1025 | (unsigned int)gid, |
| 1026 | LDAP_OBJ_POSIXACCOUNT"posixAccount", |
| 1027 | LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs"); |
| 1028 | if (filter == NULL((void*)0)) { |
| 1029 | DEBUG(3, ("talloc_asprintf failed\n"))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "1029", __FUNCTION__ )) && (dbgtext ("talloc_asprintf failed\n")) ); |
| 1030 | goto done; |
| 1031 | } |
| 1032 | |
| 1033 | rc = smbldap_search_suffix(priv->ldap_state, filter, attrs, &result); |
| 1034 | if (rc != LDAP_SUCCESS0x00) { |
| 1035 | goto done; |
| 1036 | } |
| 1037 | smbldap_talloc_autofree_ldapmsg(tmp_ctx, result); |
| 1038 | |
| 1039 | if (ldap_count_entries(priv2ld(priv), result) == 0) { |
| 1040 | DEBUG(3, ("ERROR: Got %d entries for gid %u, expected at least one\n",(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "1042", __FUNCTION__ )) && (dbgtext ("ERROR: Got %d entries for gid %u, expected at least one\n" , ldap_count_entries(priv2ld(priv), result), (unsigned int)gid )) ) |
| 1041 | ldap_count_entries(priv2ld(priv), result),(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "1042", __FUNCTION__ )) && (dbgtext ("ERROR: Got %d entries for gid %u, expected at least one\n" , ldap_count_entries(priv2ld(priv), result), (unsigned int)gid )) ) |
| 1042 | (unsigned int)gid))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "1042", __FUNCTION__ )) && (dbgtext ("ERROR: Got %d entries for gid %u, expected at least one\n" , ldap_count_entries(priv2ld(priv), result), (unsigned int)gid )) ); |
| 1043 | goto done; |
| 1044 | } |
| 1045 | |
| 1046 | for (entry = ldap_first_entry(priv2ld(priv), result); |
| 1047 | entry != NULL((void*)0); |
| 1048 | entry = ldap_next_entry(priv2ld(priv), entry)) { |
| 1049 | |
| 1050 | values = ldap_get_values_len(priv2ld(priv), entry, "objectClass"); |
| 1051 | if (values == NULL((void*)0)) { |
| 1052 | DEBUG(10, ("Cannot find any objectclasses.\n"))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "1052" , __FUNCTION__ )) && (dbgtext ("Cannot find any objectclasses.\n" )) ); |
| 1053 | goto done; |
| 1054 | } |
| 1055 | |
| 1056 | for (c = 0; values[c] != NULL((void*)0); c++) { |
| 1057 | if (strncasecmp(LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs", values[c]->bv_val, |
| 1058 | values[c]->bv_len) == 0) { |
| 1059 | goto found; |
| 1060 | } |
| 1061 | } |
| 1062 | |
| 1063 | } |
| 1064 | |
| 1065 | found: |
| 1066 | /* If we didn't find a group we found a user - so this is a primary group |
| 1067 | * For user private group, use fallback group */ |
| 1068 | if (entry == NULL((void*)0)) { |
| 1069 | |
| 1070 | DEBUG(10, ("Did not find user private group %u, "(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "1071" , __FUNCTION__ )) && (dbgtext ("Did not find user private group %u, " "returning fallback group.\n", (unsigned int)gid)) ) |
| 1071 | "returning fallback group.\n", (unsigned int)gid))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "1071" , __FUNCTION__ )) && (dbgtext ("Did not find user private group %u, " "returning fallback group.\n", (unsigned int)gid)) ); |
| 1072 | |
| 1073 | sid_copy(sid, |
| 1074 | &priv->fallback_primary_group); |
| 1075 | ret = true1; |
| 1076 | goto done; |
| 1077 | |
| 1078 | } |
| 1079 | |
| 1080 | group_sid_string = get_single_attribute(tmp_ctx, priv2ld(priv), entry, |
| 1081 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 1082 | if (group_sid_string == NULL((void*)0)) { |
| 1083 | DEBUG(1, ("Could not find SID in object '%s'\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1084", __FUNCTION__ )) && (dbgtext ("Could not find SID in object '%s'\n" , get_dn(tmp_ctx, priv2ld(priv), entry))) ) |
| 1084 | get_dn(tmp_ctx, priv2ld(priv), entry)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1084", __FUNCTION__ )) && (dbgtext ("Could not find SID in object '%s'\n" , get_dn(tmp_ctx, priv2ld(priv), entry))) ); |
| 1085 | goto done; |
| 1086 | } |
| 1087 | |
| 1088 | err = sss_idmap_sid_to_smb_sid(priv->idmap_ctx, |
| 1089 | group_sid_string, &group_sid); |
| 1090 | if (err != IDMAP_SUCCESS) { |
| 1091 | DEBUG(3, ("Error creating sid structure for sid '%s'\n",(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "1092", __FUNCTION__ )) && (dbgtext ("Error creating sid structure for sid '%s'\n" , group_sid_string)) ) |
| 1092 | group_sid_string))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "1092", __FUNCTION__ )) && (dbgtext ("Error creating sid structure for sid '%s'\n" , group_sid_string)) ); |
| 1093 | goto done; |
| 1094 | } |
| 1095 | |
| 1096 | sid_copy(sid, group_sid); |
| 1097 | |
| 1098 | ipasam_unixid_from_gid(&id, gid); |
| 1099 | |
| 1100 | idmap_cache_set_sid2unixid(sid, &id); |
| 1101 | |
| 1102 | ret = true1; |
| 1103 | |
| 1104 | done: |
| 1105 | talloc_free(group_sid)_talloc_free(group_sid, "ipa_sam.c" ":" "1105"); |
| 1106 | TALLOC_FREE(tmp_ctx)do { if (tmp_ctx != ((void*)0)) { _talloc_free(tmp_ctx, "ipa_sam.c" ":" "1106"); tmp_ctx=((void*)0); } } while(0); |
| 1107 | return ret; |
| 1108 | } |
| 1109 | |
| 1110 | #if PASSDB_INTERFACE_VERSION25 >= 24 |
| 1111 | /* Since version 24, uid_to_sid() and gid_to_sid() were removed in favor of id_to_sid() */ |
| 1112 | static bool_Bool ipasam_id_to_sid(struct pdb_methods *methods, struct unixid *id, struct dom_sid *sid) |
| 1113 | { |
| 1114 | bool_Bool result = false0; |
| 1115 | |
| 1116 | if (id->type != ID_TYPE_GID) { |
| 1117 | result = ipasam_uid_to_sid(methods, id->id, sid); |
| 1118 | } |
| 1119 | if (!result && id->type != ID_TYPE_UID) { |
| 1120 | result = ipasam_gid_to_sid(methods, id->id, sid); |
| 1121 | } |
| 1122 | |
| 1123 | return result; |
| 1124 | } |
| 1125 | #endif |
| 1126 | |
| 1127 | static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username) |
| 1128 | { |
| 1129 | char *escaped = NULL((void*)0); |
| 1130 | char *result = NULL((void*)0); |
| 1131 | |
| 1132 | escaped = escape_ldap_string(mem_ctx, username); |
| 1133 | if (escaped == NULL((void*)0)) { |
| 1134 | return NULL((void*)0); |
| 1135 | } |
| 1136 | |
| 1137 | result = talloc_asprintf(mem_ctx, "(&(uid=%s)(objectclass=%s))", |
| 1138 | escaped, LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs"); |
| 1139 | |
| 1140 | TALLOC_FREE(escaped)do { if (escaped != ((void*)0)) { _talloc_free(escaped, "ipa_sam.c" ":" "1140"); escaped=((void*)0); } } while(0); |
| 1141 | |
| 1142 | return result; |
| 1143 | } |
| 1144 | |
| 1145 | static const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...) |
| 1146 | { |
| 1147 | int i, num = 0; |
| 1148 | va_list ap; |
| 1149 | const char **result; |
| 1150 | |
| 1151 | va_start(ap, mem_ctx)__builtin_va_start(ap, mem_ctx); |
| 1152 | while (va_arg(ap, const char *)__builtin_va_arg(ap, const char *) != NULL((void*)0)) |
| 1153 | num += 1; |
| 1154 | va_end(ap)__builtin_va_end(ap); |
| 1155 | |
| 1156 | if ((result = talloc_array(mem_ctx, const char *, num+1)(const char * *)_talloc_array(mem_ctx, sizeof(const char *), num +1, "const char *")) == NULL((void*)0)) { |
| 1157 | return NULL((void*)0); |
| 1158 | } |
| 1159 | |
| 1160 | va_start(ap, mem_ctx)__builtin_va_start(ap, mem_ctx); |
| 1161 | for (i=0; i<num; i++) { |
| 1162 | result[i] = talloc_strdup(result, va_arg(ap, const char*)__builtin_va_arg(ap, const char*)); |
| 1163 | if (result[i] == NULL((void*)0)) { |
| 1164 | talloc_free(result)_talloc_free(result, "ipa_sam.c" ":" "1164"); |
| 1165 | va_end(ap)__builtin_va_end(ap); |
| 1166 | return NULL((void*)0); |
| 1167 | } |
| 1168 | } |
| 1169 | va_end(ap)__builtin_va_end(ap); |
| 1170 | |
| 1171 | result[num] = NULL((void*)0); |
| 1172 | return result; |
| 1173 | } |
| 1174 | |
| 1175 | |
| 1176 | struct ldap_search_state { |
| 1177 | struct smbldap_state *connection; |
| 1178 | |
| 1179 | uint32_t acct_flags; |
| 1180 | uint16_t group_type; |
| 1181 | |
| 1182 | const char *base; |
| 1183 | int scope; |
| 1184 | const char *filter; |
| 1185 | const char **attrs; |
| 1186 | int attrsonly; |
| 1187 | void *pagedresults_cookie; |
| 1188 | struct sss_idmap_ctx *idmap_ctx; |
| 1189 | const struct dom_sid *dom_sid; |
| 1190 | |
| 1191 | LDAPMessage *entries, *current_entry; |
| 1192 | bool_Bool (*ldap2displayentry)(struct ldap_search_state *state, |
| 1193 | TALLOC_CTX *mem_ctx, |
| 1194 | LDAP *ld, LDAPMessage *entry, |
| 1195 | struct samr_displayentry *result); |
| 1196 | }; |
| 1197 | |
| 1198 | static bool_Bool ipasam_search_firstpage(struct pdb_search *search) |
| 1199 | { |
| 1200 | struct ldap_search_state *state = |
| 1201 | talloc_get_type_abort(search->private_data, struct ldap_search_state)(struct ldap_search_state *)_talloc_get_type_abort(search-> private_data, "struct ldap_search_state", "ipa_sam.c" ":" "1201" ); |
| 1202 | LDAP *ld; |
| 1203 | int rc = LDAP_OPERATIONS_ERROR0x01; |
| 1204 | |
| 1205 | state->entries = NULL((void*)0); |
| 1206 | |
| 1207 | if (_smbldap_get_paged_results(state->connection)) { |
| 1208 | rc = smbldap_search_paged(state->connection, state->base, |
| 1209 | state->scope, state->filter, |
| 1210 | state->attrs, state->attrsonly, |
| 1211 | LDAP_PAGE_SIZE1000, &state->entries, |
| 1212 | &state->pagedresults_cookie); |
| 1213 | } |
| 1214 | |
| 1215 | if ((rc != LDAP_SUCCESS0x00) || (state->entries == NULL((void*)0))) { |
| 1216 | |
| 1217 | if (state->entries != NULL((void*)0)) { |
| 1218 | /* Left over from unsuccessful paged attempt */ |
| 1219 | ldap_msgfree(state->entries); |
| 1220 | state->entries = NULL((void*)0); |
| 1221 | } |
| 1222 | |
| 1223 | rc = smbldap_search(state->connection, state->base, |
| 1224 | state->scope, state->filter, state->attrs, |
| 1225 | state->attrsonly, &state->entries); |
| 1226 | |
| 1227 | if ((rc != LDAP_SUCCESS0x00) || (state->entries == NULL((void*)0))) |
| 1228 | return false0; |
| 1229 | |
| 1230 | /* Ok, the server was lying. It told us it could do paged |
| 1231 | * searches when it could not. */ |
| 1232 | _smbldap_set_paged_results(state->connection, false0); |
| 1233 | } |
| 1234 | |
| 1235 | ld = _smbldap_get_ldap(state->connection); |
| 1236 | if ( ld == NULL((void*)0)) { |
| 1237 | DEBUG(5, ("Don't have an LDAP connection right after a "(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1238", __FUNCTION__ )) && (dbgtext ("Don't have an LDAP connection right after a " "search\n")) ) |
| 1238 | "search\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1238", __FUNCTION__ )) && (dbgtext ("Don't have an LDAP connection right after a " "search\n")) ); |
| 1239 | return false0; |
| 1240 | } |
| 1241 | state->current_entry = ldap_first_entry(ld, state->entries); |
| 1242 | |
| 1243 | return true1; |
| 1244 | } |
| 1245 | |
| 1246 | static bool_Bool ipasam_search_nextpage(struct pdb_search *search) |
| 1247 | { |
| 1248 | struct ldap_search_state *state = |
| 1249 | talloc_get_type_abort(search->private_data, struct ldap_search_state)(struct ldap_search_state *)_talloc_get_type_abort(search-> private_data, "struct ldap_search_state", "ipa_sam.c" ":" "1249" ); |
| 1250 | LDAP *ld; |
| 1251 | int rc; |
| 1252 | |
| 1253 | if (!_smbldap_get_paged_results(state->connection)) { |
| 1254 | /* There is no next page when there are no paged results */ |
| 1255 | return false0; |
| 1256 | } |
| 1257 | |
| 1258 | rc = smbldap_search_paged(state->connection, state->base, |
| 1259 | state->scope, state->filter, state->attrs, |
| 1260 | state->attrsonly, LDAP_PAGE_SIZE1000, |
| 1261 | &state->entries, |
| 1262 | &state->pagedresults_cookie); |
| 1263 | |
| 1264 | if ((rc != LDAP_SUCCESS0x00) || (state->entries == NULL((void*)0))) |
| 1265 | return false0; |
| 1266 | |
| 1267 | ld = _smbldap_get_ldap(state->connection); |
| 1268 | if ( ld == NULL((void*)0)) { |
| 1269 | DEBUG(5, ("Don't have an LDAP connection right after a "(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1270", __FUNCTION__ )) && (dbgtext ("Don't have an LDAP connection right after a " "search\n")) ) |
| 1270 | "search\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1270", __FUNCTION__ )) && (dbgtext ("Don't have an LDAP connection right after a " "search\n")) ); |
| 1271 | return false0; |
| 1272 | } |
| 1273 | state->current_entry = ldap_first_entry(ld, |
| 1274 | state->entries); |
| 1275 | |
| 1276 | if (state->current_entry == NULL((void*)0)) { |
| 1277 | ldap_msgfree(state->entries); |
| 1278 | state->entries = NULL((void*)0); |
| 1279 | return false0; |
| 1280 | } |
| 1281 | |
| 1282 | return true1; |
| 1283 | } |
| 1284 | |
| 1285 | static bool_Bool ipasam_search_next_entry(struct pdb_search *search, |
| 1286 | struct samr_displayentry *entry) |
| 1287 | { |
| 1288 | struct ldap_search_state *state = |
| 1289 | talloc_get_type_abort(search->private_data, struct ldap_search_state)(struct ldap_search_state *)_talloc_get_type_abort(search-> private_data, "struct ldap_search_state", "ipa_sam.c" ":" "1289" ); |
| 1290 | bool_Bool result; |
| 1291 | LDAP *ld; |
| 1292 | |
| 1293 | retry: |
| 1294 | if ((state->entries == NULL((void*)0)) && (state->pagedresults_cookie == NULL((void*)0))) |
| 1295 | return false0; |
| 1296 | |
| 1297 | if ((state->entries == NULL((void*)0)) && |
| 1298 | !ipasam_search_nextpage(search)) |
| 1299 | return false0; |
| 1300 | |
| 1301 | if (state->current_entry == NULL((void*)0)) { |
| 1302 | return false0; |
| 1303 | } |
| 1304 | |
| 1305 | ld = _smbldap_get_ldap(state->connection); |
| 1306 | if ( ld == NULL((void*)0)) { |
| 1307 | DEBUG(5, ("Don't have an LDAP connection right after a "(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1308", __FUNCTION__ )) && (dbgtext ("Don't have an LDAP connection right after a " "search\n")) ) |
| 1308 | "search\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1308", __FUNCTION__ )) && (dbgtext ("Don't have an LDAP connection right after a " "search\n")) ); |
| 1309 | return false0; |
| 1310 | } |
| 1311 | result = state->ldap2displayentry(state, search, |
| 1312 | ld, |
| 1313 | state->current_entry, entry); |
| 1314 | |
| 1315 | if (!result) { |
| 1316 | char *dn; |
| 1317 | dn = ldap_get_dn(ld, state->current_entry); |
| 1318 | DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1318", __FUNCTION__ )) && (dbgtext ("Skipping entry %s\n", dn != ((void* )0) ? dn : "<NULL>")) ); |
| 1319 | if (dn != NULL((void*)0)) ldap_memfree(dn); |
| 1320 | } |
| 1321 | |
| 1322 | state->current_entry = ldap_next_entry(ld, |
| 1323 | state->current_entry); |
| 1324 | |
| 1325 | if (state->current_entry == NULL((void*)0)) { |
| 1326 | ldap_msgfree(state->entries); |
| 1327 | state->entries = NULL((void*)0); |
| 1328 | } |
| 1329 | |
| 1330 | if (!result) goto retry; |
| 1331 | |
| 1332 | return true1; |
| 1333 | } |
| 1334 | |
| 1335 | static void ipasam_search_end(struct pdb_search *search) |
| 1336 | { |
| 1337 | struct ldap_search_state *state = |
| 1338 | talloc_get_type_abort(search->private_data, struct ldap_search_state)(struct ldap_search_state *)_talloc_get_type_abort(search-> private_data, "struct ldap_search_state", "ipa_sam.c" ":" "1338" ); |
| 1339 | int rc; |
| 1340 | |
| 1341 | if (state->pagedresults_cookie == NULL((void*)0)) |
| 1342 | return; |
| 1343 | |
| 1344 | if (state->entries != NULL((void*)0)) |
| 1345 | ldap_msgfree(state->entries); |
| 1346 | |
| 1347 | state->entries = NULL((void*)0); |
| 1348 | state->current_entry = NULL((void*)0); |
| 1349 | |
| 1350 | if (!_smbldap_get_paged_results(state->connection)) |
| 1351 | return; |
| 1352 | |
| 1353 | /* Tell the LDAP server we're not interested in the rest anymore. */ |
| 1354 | |
| 1355 | rc = smbldap_search_paged(state->connection, state->base, state->scope, |
| 1356 | state->filter, state->attrs, |
| 1357 | state->attrsonly, 0, &state->entries, |
| 1358 | &state->pagedresults_cookie); |
| 1359 | |
| 1360 | if (rc != LDAP_SUCCESS0x00) |
| 1361 | DEBUG(5, ("Could not end search properly\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1361", __FUNCTION__ )) && (dbgtext ("Could not end search properly\n")) ); |
| 1362 | |
| 1363 | } |
| 1364 | |
| 1365 | static bool_Bool ldapuser2displayentry(struct ldap_search_state *state, |
| 1366 | TALLOC_CTX *mem_ctx, |
| 1367 | LDAP *ld, LDAPMessage *entry, |
| 1368 | struct samr_displayentry *result) |
| 1369 | { |
| 1370 | char **vals; |
| 1371 | size_t converted_size; |
| 1372 | struct dom_sid *sid = NULL((void*)0); |
| 1373 | enum idmap_error_code err; |
| 1374 | bool_Bool res; |
| 1375 | |
| 1376 | /* FIXME: SB try to figure out which flags to set instead of hardcode them */ |
| 1377 | result->acct_flags = 66048; |
| 1378 | result->account_name = ""; |
| 1379 | result->fullname = ""; |
| 1380 | result->description = ""; |
| 1381 | |
| 1382 | vals = ldap_get_values(ld, entry, "uid"); |
| 1383 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) { |
| 1384 | DEBUG(5, ("\"uid\" not found\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1384", __FUNCTION__ )) && (dbgtext ("\"uid\" not found\n")) ); |
| 1385 | return false0; |
| 1386 | } |
| 1387 | if (!pull_utf8_talloc(mem_ctx, |
| 1388 | discard_const_p(char *, &result->account_name)((char * *)((void *)((uintptr_t)(&result->account_name )))), |
| 1389 | vals[0], &converted_size)) |
| 1390 | { |
| 1391 | DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1392", __FUNCTION__ )) && (dbgtext ("ldapuser2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ) |
| 1392 | strerror(errno)))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1392", __FUNCTION__ )) && (dbgtext ("ldapuser2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ); |
| 1393 | } |
| 1394 | |
| 1395 | ldap_value_free(vals); |
| 1396 | |
| 1397 | vals = ldap_get_values(ld, entry, "displayName"); |
| 1398 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) |
| 1399 | DEBUG(8, ("\"displayName\" not found\n"))(void)( ((8) <= 1000) && (debuglevel_get_class(0) >= (8)) && (dbghdrclass( 8, 0, "ipa_sam.c" ":" "1399", __FUNCTION__ )) && (dbgtext ("\"displayName\" not found\n")) ); |
| 1400 | else if (!pull_utf8_talloc(mem_ctx, |
| 1401 | discard_const_p(char *, &result->fullname)((char * *)((void *)((uintptr_t)(&result->fullname)))), |
| 1402 | vals[0], &converted_size)) |
| 1403 | { |
| 1404 | DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1405", __FUNCTION__ )) && (dbgtext ("ldapuser2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ) |
| 1405 | strerror(errno)))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1405", __FUNCTION__ )) && (dbgtext ("ldapuser2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ); |
| 1406 | } |
| 1407 | |
| 1408 | ldap_value_free(vals); |
| 1409 | |
| 1410 | vals = ldap_get_values(ld, entry, "description"); |
| 1411 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) |
| 1412 | DEBUG(8, ("\"description\" not found\n"))(void)( ((8) <= 1000) && (debuglevel_get_class(0) >= (8)) && (dbghdrclass( 8, 0, "ipa_sam.c" ":" "1412", __FUNCTION__ )) && (dbgtext ("\"description\" not found\n")) ); |
| 1413 | else if (!pull_utf8_talloc(mem_ctx, |
| 1414 | discard_const_p(char *, &result->description)((char * *)((void *)((uintptr_t)(&result->description) ))), |
| 1415 | vals[0], &converted_size)) |
| 1416 | { |
| 1417 | DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1418", __FUNCTION__ )) && (dbgtext ("ldapuser2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ) |
| 1418 | strerror(errno)))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1418", __FUNCTION__ )) && (dbgtext ("ldapuser2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ); |
| 1419 | } |
| 1420 | |
| 1421 | ldap_value_free(vals); |
| 1422 | |
| 1423 | if ((result->account_name == NULL((void*)0)) || |
| 1424 | (result->fullname == NULL((void*)0)) || |
| 1425 | (result->description == NULL((void*)0))) { |
| 1426 | DEBUG(0, ("talloc failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1426", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 1427 | return false0; |
| 1428 | } |
| 1429 | |
| 1430 | vals = ldap_get_values(ld, entry, LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 1431 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) { |
| 1432 | DEBUG(0, ("\"objectSid\" not found\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1432", __FUNCTION__ )) && (dbgtext ("\"objectSid\" not found\n")) ); |
| 1433 | return false0; |
| 1434 | } |
| 1435 | |
| 1436 | err = sss_idmap_sid_to_smb_sid(state->idmap_ctx, vals[0], &sid); |
| 1437 | if (err != IDMAP_SUCCESS) { |
| 1438 | DEBUG(0, ("Could not convert %s to SID\n", vals[0]))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1438", __FUNCTION__ )) && (dbgtext ("Could not convert %s to SID\n", vals [0])) ); |
| 1439 | ldap_value_free(vals); |
| 1440 | return false0; |
| 1441 | } |
| 1442 | ldap_value_free(vals); |
| 1443 | |
| 1444 | res = sid_peek_check_rid(state->dom_sid, sid, &result->rid); |
| 1445 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "1445"); |
| 1446 | if (!res) { |
| 1447 | DEBUG(0, ("sid does not belong to our domain\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1447", __FUNCTION__ )) && (dbgtext ("sid does not belong to our domain\n" )) ); |
| 1448 | return false0; |
| 1449 | } |
| 1450 | |
| 1451 | return true1; |
| 1452 | } |
| 1453 | |
| 1454 | static bool_Bool ipasam_search_users(struct pdb_methods *methods, |
| 1455 | struct pdb_search *search, |
| 1456 | uint32_t acct_flags) |
| 1457 | { |
| 1458 | struct ipasam_private *ipasam_state = |
| 1459 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "1459"); |
| 1460 | struct ldap_search_state *state; |
| 1461 | |
| 1462 | state = talloc(search, struct ldap_search_state)(struct ldap_search_state *)talloc_named_const(search, sizeof (struct ldap_search_state), "struct ldap_search_state"); |
| 1463 | if (state == NULL((void*)0)) { |
| 1464 | DEBUG(0, ("talloc failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1464", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 1465 | return false0; |
| 1466 | } |
| 1467 | |
| 1468 | state->connection = ipasam_state->ldap_state; |
| 1469 | |
| 1470 | state->base = talloc_strdup(search, ipasam_state->base_dn); |
| 1471 | |
| 1472 | state->acct_flags = acct_flags; |
| 1473 | state->scope = LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002); |
| 1474 | state->filter = get_ldap_filter(search, "*"); |
| 1475 | state->attrs = talloc_attrs(search, "uid", LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 1476 | "displayName", "description", |
| 1477 | NULL((void*)0)); |
| 1478 | state->attrsonly = 0; |
| 1479 | state->pagedresults_cookie = NULL((void*)0); |
| 1480 | state->entries = NULL((void*)0); |
| 1481 | state->idmap_ctx = ipasam_state->idmap_ctx; |
| 1482 | state->dom_sid = &ipasam_state->domain_sid; |
| 1483 | state->ldap2displayentry = ldapuser2displayentry; |
| 1484 | |
| 1485 | if ((state->filter == NULL((void*)0)) || (state->attrs == NULL((void*)0))) { |
| 1486 | DEBUG(0, ("talloc failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1486", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 1487 | return false0; |
| 1488 | } |
| 1489 | |
| 1490 | search->private_data = state; |
| 1491 | search->next_entry = ipasam_search_next_entry; |
| 1492 | search->search_end = ipasam_search_end; |
| 1493 | |
| 1494 | return ipasam_search_firstpage(search); |
| 1495 | } |
| 1496 | |
| 1497 | static bool_Bool ldapgroup2displayentry(struct ldap_search_state *state, |
| 1498 | TALLOC_CTX *mem_ctx, |
| 1499 | LDAP *ld, LDAPMessage *entry, |
| 1500 | struct samr_displayentry *result) |
| 1501 | { |
| 1502 | char **vals = NULL((void*)0); |
| 1503 | size_t converted_size; |
| 1504 | struct dom_sid *sid = NULL((void*)0); |
| 1505 | uint16_t group_type; |
| 1506 | enum idmap_error_code err; |
| 1507 | |
| 1508 | result->account_name = ""; |
| 1509 | result->fullname = ""; |
| 1510 | result->description = ""; |
| 1511 | |
| 1512 | group_type = SID_NAME_DOM_GRP; |
| 1513 | |
| 1514 | if ((state->group_type != 0) && |
| 1515 | ((state->group_type != group_type))) { |
| 1516 | ldap_value_free(vals); |
| 1517 | return false0; |
| 1518 | } |
| 1519 | |
| 1520 | ldap_value_free(vals); |
| 1521 | |
| 1522 | /* display name is the NT group name */ |
| 1523 | |
| 1524 | vals = ldap_get_values(ld, entry, "displayName"); |
| 1525 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) { |
| 1526 | DEBUG(8, ("\"displayName\" not found\n"))(void)( ((8) <= 1000) && (debuglevel_get_class(0) >= (8)) && (dbghdrclass( 8, 0, "ipa_sam.c" ":" "1526", __FUNCTION__ )) && (dbgtext ("\"displayName\" not found\n")) ); |
| 1527 | |
| 1528 | /* fallback to the 'cn' attribute */ |
| 1529 | vals = ldap_get_values(ld, entry, "cn"); |
| 1530 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) { |
| 1531 | DEBUG(5, ("\"cn\" not found\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "1531", __FUNCTION__ )) && (dbgtext ("\"cn\" not found\n")) ); |
| 1532 | return false0; |
| 1533 | } |
| 1534 | if (!pull_utf8_talloc(mem_ctx, |
| 1535 | discard_const_p(char *,((char * *)((void *)((uintptr_t)(&result->account_name )))) |
| 1536 | &result->account_name)((char * *)((void *)((uintptr_t)(&result->account_name )))), |
| 1537 | vals[0], &converted_size)) |
| 1538 | { |
| 1539 | DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc "(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1540", __FUNCTION__ )) && (dbgtext ("ldapgroup2displayentry: pull_utf8_talloc " "failed: %s", strerror((*__errno_location ())))) ) |
| 1540 | "failed: %s", strerror(errno)))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1540", __FUNCTION__ )) && (dbgtext ("ldapgroup2displayentry: pull_utf8_talloc " "failed: %s", strerror((*__errno_location ())))) ); |
| 1541 | } |
| 1542 | } |
| 1543 | else if (!pull_utf8_talloc(mem_ctx, |
| 1544 | discard_const_p(char *,((char * *)((void *)((uintptr_t)(&result->account_name )))) |
| 1545 | &result->account_name)((char * *)((void *)((uintptr_t)(&result->account_name )))), |
| 1546 | vals[0], &converted_size)) |
| 1547 | { |
| 1548 | DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1549", __FUNCTION__ )) && (dbgtext ("ldapgroup2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ) |
| 1549 | strerror(errno)))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1549", __FUNCTION__ )) && (dbgtext ("ldapgroup2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ); |
| 1550 | } |
| 1551 | |
| 1552 | ldap_value_free(vals); |
| 1553 | |
| 1554 | vals = ldap_get_values(ld, entry, "description"); |
| 1555 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) |
| 1556 | DEBUG(8, ("\"description\" not found\n"))(void)( ((8) <= 1000) && (debuglevel_get_class(0) >= (8)) && (dbghdrclass( 8, 0, "ipa_sam.c" ":" "1556", __FUNCTION__ )) && (dbgtext ("\"description\" not found\n")) ); |
| 1557 | else if (!pull_utf8_talloc(mem_ctx, |
| 1558 | discard_const_p(char *, &result->description)((char * *)((void *)((uintptr_t)(&result->description) ))), |
| 1559 | vals[0], &converted_size)) |
| 1560 | { |
| 1561 | DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1562", __FUNCTION__ )) && (dbgtext ("ldapgroup2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ) |
| 1562 | strerror(errno)))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1562", __FUNCTION__ )) && (dbgtext ("ldapgroup2displayentry: pull_utf8_talloc failed: %s" , strerror((*__errno_location ())))) ); |
| 1563 | } |
| 1564 | ldap_value_free(vals); |
| 1565 | |
| 1566 | if ((result->account_name == NULL((void*)0)) || |
| 1567 | (result->fullname == NULL((void*)0)) || |
| 1568 | (result->description == NULL((void*)0))) { |
| 1569 | DEBUG(0, ("talloc failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1569", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 1570 | return false0; |
| 1571 | } |
| 1572 | |
| 1573 | vals = ldap_get_values(ld, entry, LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 1574 | if ((vals == NULL((void*)0)) || (vals[0] == NULL((void*)0))) { |
| 1575 | DEBUG(0, ("\"objectSid\" not found\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1575", __FUNCTION__ )) && (dbgtext ("\"objectSid\" not found\n")) ); |
| 1576 | if (vals != NULL((void*)0)) { |
| 1577 | ldap_value_free(vals); |
| 1578 | } |
| 1579 | return false0; |
| 1580 | } |
| 1581 | |
| 1582 | err = sss_idmap_sid_to_smb_sid(state->idmap_ctx, vals[0], &sid); |
| 1583 | if (err != IDMAP_SUCCESS) { |
| 1584 | DEBUG(0, ("Could not convert %s to SID\n", vals[0]))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1584", __FUNCTION__ )) && (dbgtext ("Could not convert %s to SID\n", vals [0])) ); |
| 1585 | ldap_value_free(vals); |
| 1586 | return false0; |
| 1587 | } |
| 1588 | |
| 1589 | ldap_value_free(vals); |
| 1590 | |
| 1591 | switch (group_type) { |
| 1592 | case SID_NAME_DOM_GRP: |
| 1593 | case SID_NAME_ALIAS: |
| 1594 | |
| 1595 | if (!sid_peek_check_rid(state->dom_sid, sid, &result->rid) && |
| 1596 | !sid_peek_check_rid(&global_sid_Builtin, sid, &result->rid)) |
| 1597 | { |
| 1598 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "1598"); |
| 1599 | DEBUG(0, ("SID is not in our domain\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1599", __FUNCTION__ )) && (dbgtext ("SID is not in our domain\n")) ); |
| 1600 | return false0; |
| 1601 | } |
| 1602 | break; |
| 1603 | |
| 1604 | default: |
| 1605 | DEBUG(0,("unknown group type: %d\n", group_type))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1605", __FUNCTION__ )) && (dbgtext ("unknown group type: %d\n", group_type )) ); |
| 1606 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "1606"); |
| 1607 | return false0; |
| 1608 | } |
| 1609 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "1609"); |
| 1610 | |
| 1611 | result->acct_flags = 0; |
| 1612 | |
| 1613 | return true1; |
| 1614 | } |
| 1615 | |
| 1616 | static bool_Bool ipasam_search_grouptype(struct pdb_methods *methods, |
| 1617 | struct pdb_search *search, |
| 1618 | const struct dom_sid *sid, |
| 1619 | enum lsa_SidType type) |
| 1620 | { |
| 1621 | struct ipasam_private *ipasam_state = |
| 1622 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "1622"); |
| 1623 | struct ldap_search_state *state; |
| 1624 | |
| 1625 | state = talloc(search, struct ldap_search_state)(struct ldap_search_state *)talloc_named_const(search, sizeof (struct ldap_search_state), "struct ldap_search_state"); |
| 1626 | if (state == NULL((void*)0)) { |
| 1627 | DEBUG(0, ("talloc failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1627", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 1628 | return false0; |
| 1629 | } |
| 1630 | |
| 1631 | state->base = talloc_strdup(search, ipasam_state->base_dn); |
| 1632 | state->connection = ipasam_state->ldap_state; |
| 1633 | state->scope = LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002); |
| 1634 | state->filter = talloc_asprintf(search, "(&(objectclass=%s)(%s=%s*))", |
| 1635 | LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs", LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 1636 | sid_talloc_string( |
| 1637 | ipasam_state->idmap_ctx, |
| 1638 | search, sid)); |
| 1639 | state->attrs = talloc_attrs(search, "cn", LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 1640 | "displayName", "description", |
| 1641 | NULL((void*)0)); |
| 1642 | state->attrsonly = 0; |
| 1643 | state->pagedresults_cookie = NULL((void*)0); |
| 1644 | state->entries = NULL((void*)0); |
| 1645 | state->group_type = type; |
| 1646 | state->idmap_ctx = ipasam_state->idmap_ctx; |
| 1647 | state->dom_sid = &ipasam_state->domain_sid; |
| 1648 | state->ldap2displayentry = ldapgroup2displayentry; |
| 1649 | |
| 1650 | if ((state->filter == NULL((void*)0)) || (state->attrs == NULL((void*)0))) { |
| 1651 | DEBUG(0, ("talloc failed\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1651", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 1652 | return false0; |
| 1653 | } |
| 1654 | |
| 1655 | search->private_data = state; |
| 1656 | search->next_entry = ipasam_search_next_entry; |
| 1657 | search->search_end = ipasam_search_end; |
| 1658 | |
| 1659 | return ipasam_search_firstpage(search); |
| 1660 | } |
| 1661 | |
| 1662 | static bool_Bool ipasam_search_groups(struct pdb_methods *methods, |
| 1663 | struct pdb_search *search) |
| 1664 | { |
| 1665 | struct ipasam_private *ipasam_state = |
| 1666 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "1666"); |
| 1667 | |
| 1668 | return ipasam_search_grouptype(methods, search, |
| 1669 | &ipasam_state->domain_sid, |
| 1670 | SID_NAME_DOM_GRP); |
| 1671 | } |
| 1672 | |
| 1673 | static bool_Bool ipasam_search_aliases(struct pdb_methods *methods, |
| 1674 | struct pdb_search *search, |
| 1675 | const struct dom_sid *sid) |
| 1676 | { |
| 1677 | return ipasam_search_grouptype(methods, search, |
| 1678 | sid, SID_NAME_ALIAS); |
| 1679 | } |
| 1680 | |
| 1681 | static char *trusted_domain_dn(TALLOC_CTX *mem_ctx, |
| 1682 | struct ipasam_private *ipasam_state, |
| 1683 | const char *domain) |
| 1684 | { |
| 1685 | return talloc_asprintf(mem_ctx, "%s=%s,%s", |
| 1686 | LDAP_ATTRIBUTE_CN"cn", domain, |
| 1687 | ipasam_state->trust_dn); |
| 1688 | } |
| 1689 | |
| 1690 | static NTSTATUS ipasam_get_objectclasses(struct ipasam_private *ipasam_state, |
| 1691 | const char *dn, LDAPMessage *entry, |
| 1692 | uint32_t *has_objectclass) |
| 1693 | { |
| 1694 | struct berval **bervals; |
| 1695 | size_t c; |
| 1696 | |
| 1697 | bervals = ldap_get_values_len(priv2ld(ipasam_state), entry, |
| 1698 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass"); |
| 1699 | if (bervals == NULL((void*)0)) { |
| 1700 | DEBUG(0, ("Entry [%s] does not have any objectclasses.\n", dn))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "1700", __FUNCTION__ )) && (dbgtext ("Entry [%s] does not have any objectclasses.\n" , dn)) ); |
| 1701 | return NT_STATUS_INTERNAL_DB_CORRUPTION((NTSTATUS) { 0xc00000e4 }); |
| 1702 | } |
| 1703 | |
| 1704 | *has_objectclass = 0; |
| 1705 | for (c = 0; bervals[c] != NULL((void*)0); c++) { |
| 1706 | if (strnequal(bervals[c]->bv_val, LDAP_OBJ_KRB_PRINCIPAL"krbPrincipal", bervals[c]->bv_len)) { |
| 1707 | *has_objectclass |= HAS_KRB_PRINCIPAL(1<<0); |
| 1708 | } else if (strnequal(bervals[c]->bv_val, |
| 1709 | LDAP_OBJ_KRB_PRINCIPAL_AUX"krbPrincipalAux", bervals[c]->bv_len)) { |
| 1710 | *has_objectclass |= HAS_KRB_PRINCIPAL_AUX(1<<1); |
| 1711 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_IPAOBJECT"ipaObject", bervals[c]->bv_len)) { |
| 1712 | *has_objectclass |= HAS_IPAOBJECT(1<<2); |
| 1713 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_IPAHOST"ipaHost", bervals[c]->bv_len)) { |
| 1714 | *has_objectclass |= HAS_IPAHOST(1<<3); |
| 1715 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_POSIXACCOUNT"posixAccount", bervals[c]->bv_len)) { |
| 1716 | *has_objectclass |= HAS_POSIXACCOUNT(1<<4); |
| 1717 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_GROUPOFNAMES"groupOfNames", bervals[c]->bv_len)) { |
| 1718 | *has_objectclass |= HAS_GROUPOFNAMES(1<<5); |
| 1719 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_NESTEDGROUP"nestedGroup", bervals[c]->bv_len)) { |
| 1720 | *has_objectclass |= HAS_NESTEDGROUP(1<<6); |
| 1721 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_IPAUSERGROUP"ipaUserGroup", bervals[c]->bv_len)) { |
| 1722 | *has_objectclass |= HAS_IPAUSERGROUP(1<<7); |
| 1723 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_POSIXGROUP"posixGroup", bervals[c]->bv_len)) { |
| 1724 | *has_objectclass |= HAS_POSIXGROUP(1<<8); |
| 1725 | } else if (strnequal(bervals[c]->bv_val, LDAP_OBJ_KRB_TICKET_POLICY_AUX"krbTicketPolicyAux", bervals[c]->bv_len)) { |
| 1726 | *has_objectclass |= HAS_KRB_TICKET_POLICY_AUX(1<<9); |
| 1727 | } |
| 1728 | } |
| 1729 | ldap_value_free_len(bervals); |
| 1730 | |
| 1731 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 1732 | } |
| 1733 | |
| 1734 | static bool_Bool search_krb_princ(struct ipasam_private *ipasam_state, |
| 1735 | TALLOC_CTX *mem_ctx, |
| 1736 | const char *princ, const char *base_dn, |
| 1737 | LDAPMessage **entry) |
| 1738 | { |
| 1739 | int rc; |
| 1740 | LDAPMessage *result = NULL((void*)0); |
| 1741 | uint32_t num_result; |
| 1742 | char *filter; |
| 1743 | |
| 1744 | filter = talloc_asprintf(mem_ctx, "%s=%s", |
| 1745 | LDAP_ATTRIBUTE_KRB_PRINCIPAL"krbPrincipalName", princ); |
| 1746 | if (filter == NULL((void*)0)) { |
| 1747 | return false0; |
| 1748 | } |
| 1749 | |
| 1750 | rc = smbldap_search(ipasam_state->ldap_state, base_dn, |
| 1751 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), filter, NULL((void*)0), 0, &result); |
| 1752 | |
| 1753 | if (result != NULL((void*)0)) { |
| 1754 | smbldap_talloc_autofree_ldapmsg(mem_ctx, result); |
| 1755 | } |
| 1756 | |
| 1757 | if (rc == LDAP_NO_SUCH_OBJECT0x20) { |
| 1758 | *entry = NULL((void*)0); |
| 1759 | return true1; |
| 1760 | } |
| 1761 | |
| 1762 | if (rc != LDAP_SUCCESS0x00) { |
| 1763 | return false0; |
| 1764 | } |
| 1765 | |
| 1766 | num_result = ldap_count_entries(priv2ld(ipasam_state), result); |
| 1767 | |
| 1768 | if (num_result > 1) { |
| 1769 | DEBUG(1, ("search_krb_princ: more than one object found "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1770", __FUNCTION__ )) && (dbgtext ("search_krb_princ: more than one object found " "with filter '%s'?!\n", filter)) ) |
| 1770 | "with filter '%s'?!\n", filter))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1770", __FUNCTION__ )) && (dbgtext ("search_krb_princ: more than one object found " "with filter '%s'?!\n", filter)) ); |
| 1771 | return false0; |
| 1772 | } |
| 1773 | |
| 1774 | if (num_result == 0) { |
| 1775 | DEBUG(1, ("get_trusted_domain_int: no object found "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1776", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: no object found " "with filter '%s'.\n", filter)) ) |
| 1776 | "with filter '%s'.\n", filter))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1776", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: no object found " "with filter '%s'.\n", filter)) ); |
| 1777 | *entry = NULL((void*)0); |
| 1778 | } else { |
| 1779 | *entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 1780 | } |
| 1781 | |
| 1782 | return true1; |
| 1783 | } |
| 1784 | |
| 1785 | /* Please keep ENCTYPE_ARCFOUR_HMAC the last in the list |
| 1786 | * of the default encryption types so that we can exclude |
| 1787 | * it when running in a FIPS mode where it is not allowed |
| 1788 | */ |
| 1789 | #define DEF_ENCTYPE_NUM3 3 |
| 1790 | long default_enctypes[DEF_ENCTYPE_NUM3] = { |
| 1791 | ENCTYPE_AES256_CTS_HMAC_SHA1_960x0012, |
| 1792 | ENCTYPE_AES128_CTS_HMAC_SHA1_960x0011, |
| 1793 | ENCTYPE_ARCFOUR_HMAC0x0017 |
| 1794 | }; |
| 1795 | |
| 1796 | static int set_cross_realm_pw(struct ipasam_private *ipasam_state, |
| 1797 | const char *princ, |
| 1798 | const char *pwd) |
| 1799 | { |
| 1800 | int ret; |
| 1801 | size_t buflen; |
| 1802 | void *buffer = NULL((void*)0); |
| 1803 | struct berval reqdata = { 0 }; |
| 1804 | struct berval *retdata = NULL((void*)0); |
| 1805 | char *retoid; |
| 1806 | int enctypes_num = DEF_ENCTYPE_NUM3; |
| 1807 | |
| 1808 | if (ipasam_state->fips_enabled) { |
| 1809 | DEBUG(1, ("FIPS mode enabled: TDO account credentials will not have RC4-HMAC!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1809", __FUNCTION__ )) && (dbgtext ("FIPS mode enabled: TDO account credentials will not have RC4-HMAC!\n" )) ); |
| 1810 | enctypes_num = DEF_ENCTYPE_NUM3 - 1; |
| 1811 | } |
| 1812 | ret = ipaasn1_enc_getkt(true1, princ, pwd, |
| 1813 | default_enctypes, enctypes_num, |
| 1814 | &buffer, &buflen); |
| 1815 | if (!ret) goto done; |
| 1816 | |
| 1817 | reqdata.bv_len = buflen; |
| 1818 | reqdata.bv_val = buffer; |
| 1819 | |
| 1820 | ret = smbldap_extended_operation(ipasam_state->ldap_state, |
| 1821 | KEYTAB_GET_OID"2.16.840.1.113730.3.8.10.5", &reqdata, NULL((void*)0), NULL((void*)0), |
| 1822 | &retoid, &retdata); |
| 1823 | if (ret != LDAP_SUCCESS0x00) { |
| 1824 | DEBUG(1, ("smbldap_extended_operation failed!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1824", __FUNCTION__ )) && (dbgtext ("smbldap_extended_operation failed!\n" )) ); |
| 1825 | goto done; |
| 1826 | } |
| 1827 | |
| 1828 | /* So far we do not care about the result */ |
| 1829 | ldap_memfree(retoid); |
| 1830 | if (retdata != NULL((void*)0)) { |
| 1831 | ber_bvfree(retdata); |
| 1832 | } |
| 1833 | |
| 1834 | ret = 0; |
| 1835 | done: |
| 1836 | free(buffer); |
| 1837 | return ret; |
| 1838 | } |
| 1839 | |
| 1840 | #define KRB_PRINC_CREATE_DEFAULT0x00000000 0x00000000 |
| 1841 | #define KRB_PRINC_CREATE_DISABLED0x00000001 0x00000001 |
| 1842 | #define KRB_PRINC_CREATE_AGENT_PERMISSION0x00000002 0x00000002 |
| 1843 | |
| 1844 | |
| 1845 | static bool_Bool set_krb_princ(struct ipasam_private *ipasam_state, |
| 1846 | TALLOC_CTX *mem_ctx, |
| 1847 | const char *princ, const char *alias, |
| 1848 | const char *pwd, |
| 1849 | const char *base_dn, |
| 1850 | uint32_t create_flags) |
| 1851 | { |
| 1852 | LDAPMessage *entry = NULL((void*)0); |
| 1853 | LDAPMod **mods = NULL((void*)0); |
| 1854 | char *dn = NULL((void*)0); |
| 1855 | int ret; |
| 1856 | uint32_t has_objectclass = 0; |
| 1857 | NTSTATUS status; |
| 1858 | |
| 1859 | if (!search_krb_princ(ipasam_state, mem_ctx, princ, base_dn, &entry)) { |
| 1860 | return false0; |
| 1861 | } |
| 1862 | |
| 1863 | if (entry) { |
| 1864 | dn = get_dn(mem_ctx, priv2ld(ipasam_state), entry); |
| 1865 | if (!dn) { |
| 1866 | return false0; |
| 1867 | } |
| 1868 | |
| 1869 | status = ipasam_get_objectclasses(ipasam_state, dn, entry, |
| 1870 | &has_objectclass); |
| 1871 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 1872 | return false0; |
| 1873 | } |
| 1874 | } else { |
| 1875 | dn = talloc_asprintf(mem_ctx, "%s=%s,%s", |
| 1876 | LDAP_ATTRIBUTE_KRB_PRINCIPAL"krbPrincipalName", princ, |
| 1877 | base_dn); |
| 1878 | if (!dn) { |
| 1879 | return false0; |
| 1880 | } |
| 1881 | } |
| 1882 | |
| 1883 | if (!(has_objectclass & HAS_KRB_PRINCIPAL(1<<0))) { |
| 1884 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1885 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 1886 | LDAP_OBJ_KRB_PRINCIPAL"krbPrincipal"); |
| 1887 | } |
| 1888 | |
| 1889 | if (!(has_objectclass & HAS_KRB_PRINCIPAL_AUX(1<<1))) { |
| 1890 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1891 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 1892 | LDAP_OBJ_KRB_PRINCIPAL_AUX"krbPrincipalAux"); |
| 1893 | } |
| 1894 | |
| 1895 | if (!(has_objectclass & HAS_KRB_TICKET_POLICY_AUX(1<<9))) { |
| 1896 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1897 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 1898 | LDAP_OBJ_KRB_TICKET_POLICY_AUX"krbTicketPolicyAux"); |
| 1899 | } |
| 1900 | |
| 1901 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1902 | LDAP_ATTRIBUTE_KRB_CANONICAL"krbCanonicalName", princ); |
| 1903 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1904 | LDAP_ATTRIBUTE_KRB_PRINCIPAL"krbPrincipalName", princ); |
| 1905 | if (alias) { |
| 1906 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1907 | LDAP_ATTRIBUTE_KRB_PRINCIPAL"krbPrincipalName", alias); |
| 1908 | } |
| 1909 | |
| 1910 | if ((create_flags & KRB_PRINC_CREATE_DISABLED0x00000001)) { |
| 1911 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1912 | LDAP_ATTRIBUTE_KRB_TICKET_FLAGS"krbTicketFlags", |
| 1913 | __TALLOC_STRING_LINE2__(IPASAM_DISALLOW_ALL_TIX)"64"); |
| 1914 | } |
| 1915 | |
| 1916 | if ((create_flags & KRB_PRINC_CREATE_AGENT_PERMISSION0x00000002)) { |
| 1917 | char *agent_dn = NULL((void*)0); |
| 1918 | agent_dn = talloc_asprintf(mem_ctx, LDAP_CN_ADTRUST_AGENTS"cn=adtrust agents,cn=sysaccounts,cn=etc"",%s", ipasam_state->base_dn); |
| 1919 | if (agent_dn == NULL((void*)0)) { |
| 1920 | DEBUG(1, ("error configuring cross realm principal data!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1920", __FUNCTION__ )) && (dbgtext ("error configuring cross realm principal data!\n" )) ); |
| 1921 | return false0; |
| 1922 | } |
| 1923 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1924 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 1925 | LDAP_OBJ_IPAOPALLOW"ipaAllowedOperations"); |
| 1926 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1927 | LDAP_ATTRIBUTE_IPAOPALLOW"ipaAllowedToPerform;read_keys", |
| 1928 | agent_dn); |
| 1929 | agent_dn = talloc_asprintf(mem_ctx, LDAP_CN_ADTRUST_ADMINS"cn=trust admins,cn=groups,cn=accounts"",%s", ipasam_state->base_dn); |
| 1930 | if (agent_dn == NULL((void*)0)) { |
| 1931 | DEBUG(1, ("error configuring cross realm principal data for trust admins!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1931", __FUNCTION__ )) && (dbgtext ("error configuring cross realm principal data for trust admins!\n" )) ); |
| 1932 | return false0; |
| 1933 | } |
| 1934 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), |
| 1935 | LDAP_ATTRIBUTE_IPAOPALLOW"ipaAllowedToPerform;read_keys", |
| 1936 | agent_dn); |
| 1937 | } |
| 1938 | |
| 1939 | if (entry == NULL((void*)0)) { |
| 1940 | ret = smbldap_add(ipasam_state->ldap_state, dn, mods); |
| 1941 | } else { |
| 1942 | ret = smbldap_modify(ipasam_state->ldap_state, dn, mods); |
| 1943 | } |
| 1944 | if (ret != LDAP_SUCCESS0x00) { |
| 1945 | DEBUG(1, ("error writing cross realm principal data!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1945", __FUNCTION__ )) && (dbgtext ("error writing cross realm principal data!\n" )) ); |
| 1946 | return false0; |
| 1947 | } |
| 1948 | |
| 1949 | ret = set_cross_realm_pw(ipasam_state, princ, pwd); |
| 1950 | if (ret != 0) { |
| 1951 | DEBUG(1, ("set_cross_realm_pw failed.\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "1951", __FUNCTION__ )) && (dbgtext ("set_cross_realm_pw failed.\n")) ); |
| 1952 | return false0; |
| 1953 | } |
| 1954 | |
| 1955 | return true1; |
| 1956 | } |
| 1957 | |
| 1958 | static bool_Bool del_krb_princ(struct ipasam_private *ipasam_state, |
| 1959 | TALLOC_CTX *mem_ctx, |
| 1960 | const char *princ, const char *base_dn) |
| 1961 | { |
| 1962 | LDAPMessage *entry = NULL((void*)0); |
| 1963 | char *dn = NULL((void*)0); |
| 1964 | int ret; |
| 1965 | |
| 1966 | if (!search_krb_princ(ipasam_state, mem_ctx, princ, base_dn, &entry)) { |
| 1967 | return false0; |
| 1968 | } |
| 1969 | |
| 1970 | if (entry) { |
| 1971 | dn = get_dn(mem_ctx, priv2ld(ipasam_state), entry); |
| 1972 | if (!dn) { |
| 1973 | return false0; |
| 1974 | } |
| 1975 | |
| 1976 | ret = smbldap_delete(ipasam_state->ldap_state, dn); |
| 1977 | if (ret != LDAP_SUCCESS0x00) { |
| 1978 | return false0; |
| 1979 | } |
| 1980 | } |
| 1981 | |
| 1982 | return true1; |
| 1983 | } |
| 1984 | |
| 1985 | enum princ_mod { |
| 1986 | SET_PRINC, |
| 1987 | DEL_PRINC |
| 1988 | }; |
| 1989 | |
| 1990 | static bool_Bool handle_cross_realm_princs(struct ipasam_private *ipasam_state, |
| 1991 | const char *domain, const char *flat_name, |
| 1992 | const char *pwd_incoming, |
| 1993 | const char *pwd_outgoing, |
| 1994 | uint32_t trust_direction, |
| 1995 | enum princ_mod mod) |
| 1996 | { |
| 1997 | char *trusted_dn; |
| 1998 | char *princ_l; |
| 1999 | char *princ_r; |
| 2000 | char *princ_r_tdo, *princ_l_tdo; |
| 2001 | char *remote_realm; |
| 2002 | bool_Bool ok; |
| 2003 | int failed = 0; |
| 2004 | TALLOC_CTX *tmp_ctx; |
| 2005 | const char *r_tdo_alias, *l_tdo_alias; |
| 2006 | |
| 2007 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "2007"); |
| 2008 | if (tmp_ctx == NULL((void*)0)) { |
| 2009 | return false0; |
| 2010 | } |
| 2011 | |
| 2012 | remote_realm = talloc_strdup_upper(tmp_ctx, domain); |
| 2013 | if (remote_realm == NULL((void*)0)) { |
| 2014 | ok = false0; |
| 2015 | goto done; |
| 2016 | } |
| 2017 | |
| 2018 | trusted_dn = trusted_domain_dn(tmp_ctx, ipasam_state, domain); |
| 2019 | |
| 2020 | princ_l = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", |
| 2021 | remote_realm, ipasam_state->realm); |
| 2022 | princ_l_tdo = talloc_asprintf(tmp_ctx, "%s$@%s", |
| 2023 | flat_name, ipasam_state->realm); |
| 2024 | l_tdo_alias = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", |
| 2025 | flat_name, ipasam_state->realm); |
| 2026 | |
| 2027 | princ_r = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", |
| 2028 | ipasam_state->realm, remote_realm); |
| 2029 | princ_r_tdo = talloc_asprintf(tmp_ctx, "%s$@%s", |
| 2030 | ipasam_state->flat_name, remote_realm); |
| 2031 | |
| 2032 | r_tdo_alias = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", |
| 2033 | ipasam_state->flat_name, remote_realm); |
| 2034 | |
| 2035 | if (trusted_dn == NULL((void*)0) || princ_l == NULL((void*)0) || princ_l_tdo == NULL((void*)0) || |
| 2036 | l_tdo_alias == NULL((void*)0) || princ_r == NULL((void*)0) || princ_r_tdo == NULL((void*)0) || |
| 2037 | r_tdo_alias == NULL((void*)0)) { |
| 2038 | ok = false0; |
| 2039 | goto done; |
| 2040 | } |
| 2041 | |
| 2042 | switch (mod) { |
| 2043 | case SET_PRINC: |
| 2044 | /* We must use two sets by two principals here because |
| 2045 | * they are used for different needs and must have |
| 2046 | * different salts */ |
| 2047 | |
| 2048 | failed = 0; |
| 2049 | /* INBOUND TRUST */ |
| 2050 | if ((trust_direction & LSA_TRUST_DIRECTION_INBOUND( 0x00000001 )) != 0) { |
| 2051 | /* First: krbtgt/<OUR REALM>@<REMOTE REALM>, enabled by default |
| 2052 | * in case of the inboud trust */ |
| 2053 | failed += !set_krb_princ(ipasam_state, tmp_ctx, princ_r, NULL((void*)0), |
| 2054 | pwd_outgoing, trusted_dn, |
| 2055 | KRB_PRINC_CREATE_DEFAULT0x00000000); |
| 2056 | |
| 2057 | /* Second: krbtgt/<OUR FLATNAME>@<REMOTE REALM> |
| 2058 | * is only used for SSSD to be able to talk to |
| 2059 | * AD DCs but it has to have canonical name set |
| 2060 | * to krbtgt/<OUR FLATNAME> and alias it to |
| 2061 | * <OUR FLATNAME$> because it is the salt used |
| 2062 | * by AD DCs when using this principal, |
| 2063 | * otherwise authentication will fail. |
| 2064 | * |
| 2065 | * *disable* use of this principal on our side as it is |
| 2066 | * only used to retrieve trusted domain credentials by |
| 2067 | * AD Trust Agents across the IPA topology */ |
| 2068 | failed += !set_krb_princ(ipasam_state, tmp_ctx, |
| 2069 | r_tdo_alias, princ_r_tdo, |
| 2070 | pwd_incoming, trusted_dn, |
| 2071 | (KRB_PRINC_CREATE_DISABLED0x00000001 | |
| 2072 | KRB_PRINC_CREATE_AGENT_PERMISSION0x00000002)); |
| 2073 | |
| 2074 | ok = (failed == 0); |
| 2075 | if (!ok) { |
| 2076 | goto done; |
| 2077 | } |
| 2078 | } |
| 2079 | |
| 2080 | failed = 0; |
| 2081 | /* OUTBOUND TRUST */ |
| 2082 | if ((trust_direction & LSA_TRUST_DIRECTION_OUTBOUND( 0x00000002 )) != 0) { |
| 2083 | /* First: krbtgt/<REMOTE REALM>@<OUR REALM>, enabled by default */ |
| 2084 | failed += !set_krb_princ(ipasam_state, tmp_ctx, |
| 2085 | princ_l, NULL((void*)0), |
| 2086 | pwd_outgoing, trusted_dn, |
| 2087 | KRB_PRINC_CREATE_DEFAULT0x00000000); |
| 2088 | |
| 2089 | /* Second: <REMOTE FLAT NAME>$@<OUR REALM>, enabled by default |
| 2090 | * as it is used for a remote DC to authenticate against IPA Samba |
| 2091 | * |
| 2092 | * A local account for the outbound trust must have |
| 2093 | * POSIX and SMB identities associated with our domain but we associate |
| 2094 | * them with the trust domain object itself */ |
| 2095 | failed += !set_krb_princ(ipasam_state, tmp_ctx, |
| 2096 | princ_l_tdo, l_tdo_alias, |
| 2097 | pwd_incoming, trusted_dn, |
| 2098 | KRB_PRINC_CREATE_DEFAULT0x00000000); |
| 2099 | |
| 2100 | ok = (failed == 0); |
| 2101 | if (!ok) { |
| 2102 | goto done; |
| 2103 | } |
| 2104 | } |
| 2105 | break; |
| 2106 | case DEL_PRINC: |
| 2107 | failed = 0; |
| 2108 | if ((trust_direction & LSA_TRUST_DIRECTION_INBOUND( 0x00000001 )) != 0) { |
| 2109 | failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_r, trusted_dn); |
| 2110 | failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_r_tdo, trusted_dn); |
| 2111 | |
| 2112 | ok = (failed == 0); |
| 2113 | if (!ok) { |
| 2114 | goto done; |
| 2115 | } |
| 2116 | } |
| 2117 | |
| 2118 | failed = 0; |
| 2119 | if ((trust_direction & LSA_TRUST_DIRECTION_OUTBOUND( 0x00000002 )) != 0) { |
| 2120 | failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_l, trusted_dn); |
| 2121 | failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_l_tdo, trusted_dn); |
| 2122 | |
| 2123 | ok = (failed == 0); |
| 2124 | if (!ok) { |
| 2125 | goto done; |
| 2126 | } |
| 2127 | } |
| 2128 | break; |
| 2129 | default: |
| 2130 | DEBUG(1, ("unknown operation.\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2130", __FUNCTION__ )) && (dbgtext ("unknown operation.\n")) ); |
| 2131 | ok = false0; |
| 2132 | goto done; |
| 2133 | } |
| 2134 | |
| 2135 | ok = true1; |
| 2136 | done: |
| 2137 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "2137"); |
| 2138 | return ok; |
| 2139 | } |
| 2140 | |
| 2141 | static bool_Bool set_cross_realm_princs(struct ipasam_private *ipasam_state, |
| 2142 | const char *domain, const char* flat_name, |
| 2143 | const char *pwd_incoming, const char *pwd_outgoing, |
| 2144 | uint32_t trust_direction) |
| 2145 | { |
| 2146 | return handle_cross_realm_princs(ipasam_state, domain, flat_name, |
| 2147 | pwd_incoming, |
| 2148 | pwd_outgoing, |
| 2149 | trust_direction, SET_PRINC); |
| 2150 | } |
| 2151 | |
| 2152 | static bool_Bool del_cross_realm_princs(struct ipasam_private *ipasam_state, |
| 2153 | const char *domain, const char *flat_name) |
| 2154 | { |
| 2155 | uint32_t trust_direction = LSA_TRUST_DIRECTION_INBOUND( 0x00000001 ) | LSA_TRUST_DIRECTION_OUTBOUND( 0x00000002 ); |
| 2156 | return handle_cross_realm_princs(ipasam_state, domain, flat_name, |
| 2157 | NULL((void*)0), NULL((void*)0), trust_direction, DEL_PRINC); |
| 2158 | } |
| 2159 | |
| 2160 | static bool_Bool get_trusted_domain_int(struct ipasam_private *ipasam_state, |
| 2161 | TALLOC_CTX *mem_ctx, |
| 2162 | const char *filter, LDAPMessage **entry) |
| 2163 | { |
| 2164 | int rc; |
| 2165 | LDAPMessage *result = NULL((void*)0); |
| 2166 | uint32_t num_result; |
| 2167 | |
| 2168 | rc = smbldap_search(ipasam_state->ldap_state, |
| 2169 | ipasam_state->trust_dn, |
| 2170 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), filter, NULL((void*)0), 0, &result); |
| 2171 | |
| 2172 | if (result != NULL((void*)0)) { |
| 2173 | smbldap_talloc_autofree_ldapmsg(mem_ctx, result); |
| 2174 | } |
| 2175 | |
| 2176 | if (rc == LDAP_NO_SUCH_OBJECT0x20) { |
| 2177 | *entry = NULL((void*)0); |
| 2178 | return true1; |
| 2179 | } |
| 2180 | |
| 2181 | if (rc != LDAP_SUCCESS0x00) { |
| 2182 | return false0; |
| 2183 | } |
| 2184 | |
| 2185 | num_result = ldap_count_entries(priv2ld(ipasam_state), result); |
| 2186 | |
| 2187 | if (num_result > 1) { |
| 2188 | DEBUG(1, ("get_trusted_domain_int: more than one "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2190", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: more than one " "%s object with filter '%s'?!\n", "ipaNTTrustedDomain", filter )) ) |
| 2189 | "%s object with filter '%s'?!\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2190", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: more than one " "%s object with filter '%s'?!\n", "ipaNTTrustedDomain", filter )) ) |
| 2190 | LDAP_OBJ_TRUSTED_DOMAIN, filter))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2190", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: more than one " "%s object with filter '%s'?!\n", "ipaNTTrustedDomain", filter )) ); |
| 2191 | return false0; |
| 2192 | } |
| 2193 | |
| 2194 | if (num_result == 0) { |
| 2195 | DEBUG(1, ("get_trusted_domain_int: no "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2197", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: no " "%s object with filter '%s'.\n" , "ipaNTTrustedDomain", filter)) ) |
| 2196 | "%s object with filter '%s'.\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2197", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: no " "%s object with filter '%s'.\n" , "ipaNTTrustedDomain", filter)) ) |
| 2197 | LDAP_OBJ_TRUSTED_DOMAIN, filter))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2197", __FUNCTION__ )) && (dbgtext ("get_trusted_domain_int: no " "%s object with filter '%s'.\n" , "ipaNTTrustedDomain", filter)) ); |
| 2198 | *entry = NULL((void*)0); |
| 2199 | } else { |
| 2200 | *entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 2201 | } |
| 2202 | |
| 2203 | return true1; |
| 2204 | } |
| 2205 | |
| 2206 | static bool_Bool get_trusted_domain_by_name_int(struct ipasam_private *ipasam_state, |
| 2207 | TALLOC_CTX *mem_ctx, |
| 2208 | const char *domain, |
| 2209 | LDAPMessage **entry) |
| 2210 | { |
| 2211 | char *filter = NULL((void*)0); |
| 2212 | bool_Bool ok; |
| 2213 | |
| 2214 | filter = talloc_asprintf(mem_ctx, |
| 2215 | "(&(objectClass=%s)(|(%s=%s)(%s=%s)(cn=%s)))", |
| 2216 | LDAP_OBJ_TRUSTED_DOMAIN"ipaNTTrustedDomain", |
| 2217 | LDAP_ATTRIBUTE_FLAT_NAME"ipaNTFlatName", domain, |
| 2218 | LDAP_ATTRIBUTE_TRUST_PARTNER"ipaNTTrustPartner", domain, domain); |
| 2219 | if (filter == NULL((void*)0)) { |
| 2220 | return false0; |
| 2221 | } |
| 2222 | |
| 2223 | ok = get_trusted_domain_int(ipasam_state, mem_ctx, filter, entry); |
| 2224 | talloc_free(filter)_talloc_free(filter, "ipa_sam.c" ":" "2224"); |
| 2225 | |
| 2226 | return ok; |
| 2227 | } |
| 2228 | |
| 2229 | static bool_Bool get_trusted_domain_by_sid_int(struct ipasam_private *ipasam_state, |
| 2230 | TALLOC_CTX *mem_ctx, |
| 2231 | const char *sid, LDAPMessage **entry) |
| 2232 | { |
| 2233 | char *filter = NULL((void*)0); |
| 2234 | bool_Bool ok; |
| 2235 | |
| 2236 | filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))", |
| 2237 | LDAP_OBJ_TRUSTED_DOMAIN"ipaNTTrustedDomain", |
| 2238 | LDAP_ATTRIBUTE_TRUST_SID"ipaNTTrustedDomainSID", sid); |
| 2239 | if (filter == NULL((void*)0)) { |
| 2240 | return false0; |
| 2241 | } |
| 2242 | |
| 2243 | ok = get_trusted_domain_int(ipasam_state, mem_ctx, filter, entry); |
| 2244 | talloc_free(filter)_talloc_free(filter, "ipa_sam.c" ":" "2244"); |
| 2245 | |
| 2246 | return ok; |
| 2247 | } |
| 2248 | |
| 2249 | static bool_Bool get_uint32_t_from_ldap_msg(struct ipasam_private *ipasam_state, |
| 2250 | LDAPMessage *entry, |
| 2251 | const char *attr, |
| 2252 | uint32_t *val) |
| 2253 | { |
| 2254 | char *dummy; |
| 2255 | long int l; |
| 2256 | char *endptr; |
| 2257 | |
| 2258 | dummy = get_single_attribute(NULL((void*)0), priv2ld(ipasam_state), entry, attr); |
| 2259 | if (dummy == NULL((void*)0)) { |
| 2260 | DEBUG(9, ("Attribute %s not present.\n", attr))(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2260", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", attr) ) ); |
| 2261 | *val = 0; |
| 2262 | return true1; |
| 2263 | } |
| 2264 | |
| 2265 | l = strtoul(dummy, &endptr, 10); |
| 2266 | |
| 2267 | if (l < 0 || l > UINT32_MAX(4294967295U) || *endptr != '\0') { |
| 2268 | TALLOC_FREE(dummy)do { if (dummy != ((void*)0)) { _talloc_free(dummy, "ipa_sam.c" ":" "2268"); dummy=((void*)0); } } while(0); |
| 2269 | return false0; |
| 2270 | } |
| 2271 | TALLOC_FREE(dummy)do { if (dummy != ((void*)0)) { _talloc_free(dummy, "ipa_sam.c" ":" "2271"); dummy=((void*)0); } } while(0); |
| 2272 | |
| 2273 | *val = l; |
| 2274 | |
| 2275 | return true1; |
| 2276 | } |
| 2277 | |
| 2278 | static bool_Bool fill_pdb_trusted_domain(TALLOC_CTX *mem_ctx, |
| 2279 | struct ipasam_private *ipasam_state, |
| 2280 | LDAPMessage *entry, |
| 2281 | struct pdb_trusted_domain **_td) |
| 2282 | { |
| 2283 | char *dummy; |
| 2284 | bool_Bool res; |
| 2285 | struct pdb_trusted_domain *td; |
| 2286 | struct dom_sid *sid = NULL((void*)0); |
| 2287 | enum idmap_error_code err; |
| 2288 | |
| 2289 | if (entry == NULL((void*)0)) { |
| 2290 | return false0; |
| 2291 | } |
| 2292 | |
| 2293 | td = talloc_zero(mem_ctx, struct pdb_trusted_domain)(struct pdb_trusted_domain *)_talloc_zero(mem_ctx, sizeof(struct pdb_trusted_domain), "struct pdb_trusted_domain"); |
| 2294 | if (td == NULL((void*)0)) { |
| 2295 | return false0; |
| 2296 | } |
| 2297 | |
| 2298 | /* All attributes are MAY */ |
| 2299 | |
| 2300 | dummy = get_single_attribute(NULL((void*)0), priv2ld(ipasam_state), entry, |
| 2301 | LDAP_ATTRIBUTE_TRUST_SID"ipaNTTrustedDomainSID"); |
| 2302 | if (dummy == NULL((void*)0)) { |
| 2303 | DEBUG(9, ("Attribute %s not present.\n",(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2304", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTTrustedDomainSID" )) ) |
| 2304 | LDAP_ATTRIBUTE_TRUST_SID))(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2304", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTTrustedDomainSID" )) ); |
| 2305 | } else { |
| 2306 | err = sss_idmap_sid_to_smb_sid(ipasam_state->idmap_ctx, |
| 2307 | dummy, &sid); |
| 2308 | TALLOC_FREE(dummy)do { if (dummy != ((void*)0)) { _talloc_free(dummy, "ipa_sam.c" ":" "2308"); dummy=((void*)0); } } while(0); |
| 2309 | if (err != IDMAP_SUCCESS) { |
| 2310 | return false0; |
| 2311 | } |
| 2312 | sid_copy(&td->security_identifier, sid); |
| 2313 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "2313"); |
| 2314 | } |
| 2315 | |
| 2316 | if (!smbldap_talloc_single_blob(td, priv2ld(ipasam_state), entry, |
| 2317 | LDAP_ATTRIBUTE_TRUST_AUTH_INCOMING"ipaNTTrustAuthIncoming", |
| 2318 | &td->trust_auth_incoming)) { |
| 2319 | DEBUG(9, ("Failed to set incoming auth info.\n"))(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2319", __FUNCTION__ )) && (dbgtext ("Failed to set incoming auth info.\n" )) ); |
| 2320 | } |
| 2321 | |
| 2322 | |
| 2323 | if (!smbldap_talloc_single_blob(td, priv2ld(ipasam_state), entry, |
| 2324 | LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING"ipaNTTrustAuthOutgoing", |
| 2325 | &td->trust_auth_outgoing)) { |
| 2326 | DEBUG(9, ("Failed to set outgoing auth info.\n"))(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2326", __FUNCTION__ )) && (dbgtext ("Failed to set outgoing auth info.\n" )) ); |
| 2327 | } |
| 2328 | |
| 2329 | td->netbios_name = get_single_attribute(td, priv2ld(ipasam_state), entry, |
| 2330 | LDAP_ATTRIBUTE_FLAT_NAME"ipaNTFlatName"); |
| 2331 | if (td->netbios_name == NULL((void*)0)) { |
| 2332 | DEBUG(9, ("Attribute %s not present.\n",(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2333", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTFlatName" )) ) |
| 2333 | LDAP_ATTRIBUTE_FLAT_NAME))(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2333", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTFlatName" )) ); |
| 2334 | } |
| 2335 | |
| 2336 | td->domain_name = get_single_attribute(td, priv2ld(ipasam_state), entry, |
| 2337 | LDAP_ATTRIBUTE_TRUST_PARTNER"ipaNTTrustPartner"); |
| 2338 | if (td->domain_name == NULL((void*)0)) { |
| 2339 | DEBUG(9, ("Attribute %s not present.\n",(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2340", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTTrustPartner" )) ) |
| 2340 | LDAP_ATTRIBUTE_TRUST_PARTNER))(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2340", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTTrustPartner" )) ); |
| 2341 | } |
| 2342 | |
| 2343 | res = get_uint32_t_from_ldap_msg(ipasam_state, entry, |
| 2344 | LDAP_ATTRIBUTE_TRUST_DIRECTION"ipaNTTrustDirection", |
| 2345 | &td->trust_direction); |
| 2346 | if (!res) { |
| 2347 | return false0; |
| 2348 | } |
| 2349 | if (td->trust_direction == 0) { |
| 2350 | /* attribute wasn't present, set default value */ |
| 2351 | td->trust_direction = LSA_TRUST_DIRECTION_INBOUND( 0x00000001 ) | LSA_TRUST_DIRECTION_OUTBOUND( 0x00000002 ); |
| 2352 | } |
| 2353 | |
| 2354 | res = get_uint32_t_from_ldap_msg(ipasam_state, entry, |
| 2355 | LDAP_ATTRIBUTE_TRUST_ATTRIBUTES"ipaNTTrustAttributes", |
| 2356 | &td->trust_attributes); |
| 2357 | if (!res) { |
| 2358 | return false0; |
| 2359 | } |
| 2360 | if (td->trust_attributes == 0) { |
| 2361 | /* attribute wasn't present, set default value */ |
| 2362 | td->trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE( 0x00000008 ); |
| 2363 | } |
| 2364 | |
| 2365 | res = get_uint32_t_from_ldap_msg(ipasam_state, entry, |
| 2366 | LDAP_ATTRIBUTE_TRUST_TYPE"ipaNTTrustType", |
| 2367 | &td->trust_type); |
| 2368 | if (!res) { |
| 2369 | return false0; |
| 2370 | } |
| 2371 | if (td->trust_type == 0) { |
| 2372 | /* attribute wasn't present, set default value */ |
| 2373 | td->trust_type = LSA_TRUST_TYPE_UPLEVEL; |
| 2374 | } |
| 2375 | |
| 2376 | td->trust_posix_offset = talloc_zero(td, uint32_t)(uint32_t *)_talloc_zero(td, sizeof(uint32_t), "uint32_t"); |
| 2377 | if (td->trust_posix_offset == NULL((void*)0)) { |
| 2378 | return false0; |
| 2379 | } |
| 2380 | res = get_uint32_t_from_ldap_msg(ipasam_state, entry, |
| 2381 | LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET"ipaNTTrustPosixOffset", |
| 2382 | td->trust_posix_offset); |
| 2383 | if (!res) { |
| 2384 | return false0; |
| 2385 | } |
| 2386 | |
| 2387 | td->supported_enc_type = talloc_zero(td, uint32_t)(uint32_t *)_talloc_zero(td, sizeof(uint32_t), "uint32_t"); |
| 2388 | if (td->supported_enc_type == NULL((void*)0)) { |
| 2389 | return false0; |
| 2390 | } |
| 2391 | res = get_uint32_t_from_ldap_msg(ipasam_state, entry, |
| 2392 | LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE"ipaNTSupportedEncryptionTypes", |
| 2393 | td->supported_enc_type); |
| 2394 | if (!res) { |
| 2395 | return false0; |
| 2396 | } |
| 2397 | if (*td->supported_enc_type == 0) { |
| 2398 | *td->supported_enc_type = ipasam_state->supported_enctypes; |
| 2399 | } |
| 2400 | |
| 2401 | if (!smbldap_talloc_single_blob(td, priv2ld(ipasam_state), entry, |
| 2402 | LDAP_ATTRIBUTE_TRUST_FOREST_TRUST_INFO"ipaNTTrustForestTrustInfo", |
| 2403 | &td->trust_forest_trust_info)) { |
| 2404 | DEBUG(9, ("Failed to set forest trust info.\n"))(void)( ((9) <= 1000) && (debuglevel_get_class(0) >= (9)) && (dbghdrclass( 9, 0, "ipa_sam.c" ":" "2404", __FUNCTION__ )) && (dbgtext ("Failed to set forest trust info.\n" )) ); |
| 2405 | } |
| 2406 | |
| 2407 | *_td = td; |
| 2408 | |
| 2409 | return true1; |
| 2410 | } |
| 2411 | |
| 2412 | static NTSTATUS ipasam_get_trusted_domain(struct pdb_methods *methods, |
| 2413 | TALLOC_CTX *mem_ctx, |
| 2414 | const char *domain, |
| 2415 | struct pdb_trusted_domain **td) |
| 2416 | { |
| 2417 | struct ipasam_private *ipasam_state = |
| 2418 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "2418"); |
| 2419 | LDAPMessage *entry = NULL((void*)0); |
| 2420 | |
| 2421 | DEBUG(10, ("ipasam_get_trusted_domain called for domain %s\n", domain))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "2421" , __FUNCTION__ )) && (dbgtext ("ipasam_get_trusted_domain called for domain %s\n" , domain)) ); |
| 2422 | |
| 2423 | if (!get_trusted_domain_by_name_int(ipasam_state, mem_ctx, domain, |
| 2424 | &entry)) { |
| 2425 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2426 | } |
| 2427 | if (entry == NULL((void*)0)) { |
| 2428 | DEBUG(5, ("ipasam_get_trusted_domain: no such trusted domain: "(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "2429", __FUNCTION__ )) && (dbgtext ("ipasam_get_trusted_domain: no such trusted domain: " "%s\n", domain)) ) |
| 2429 | "%s\n", domain))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "2429", __FUNCTION__ )) && (dbgtext ("ipasam_get_trusted_domain: no such trusted domain: " "%s\n", domain)) ); |
| 2430 | return NT_STATUS_NO_SUCH_DOMAIN((NTSTATUS) { 0xc00000df }); |
| 2431 | } |
| 2432 | |
| 2433 | if (!fill_pdb_trusted_domain(mem_ctx, ipasam_state, entry, td)) { |
| 2434 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2435 | } |
| 2436 | |
| 2437 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 2438 | } |
| 2439 | |
| 2440 | static NTSTATUS ipasam_get_trusted_domain_by_sid(struct pdb_methods *methods, |
| 2441 | TALLOC_CTX *mem_ctx, |
| 2442 | struct dom_sid *sid, |
| 2443 | struct pdb_trusted_domain **td) |
| 2444 | { |
| 2445 | struct ipasam_private *ipasam_state = |
| 2446 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "2446"); |
| 2447 | LDAPMessage *entry = NULL((void*)0); |
| 2448 | char *sid_str; |
| 2449 | bool_Bool ok; |
| 2450 | |
| 2451 | sid_str = sid_talloc_string(ipasam_state->idmap_ctx, mem_ctx, sid); |
| 2452 | if (sid_str == NULL((void*)0)) { |
| 2453 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2454 | } |
| 2455 | |
| 2456 | DEBUG(10, ("ipasam_get_trusted_domain_by_sid called for sid %s\n",(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "2457" , __FUNCTION__ )) && (dbgtext ("ipasam_get_trusted_domain_by_sid called for sid %s\n" , sid_str)) ) |
| 2457 | sid_str))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "2457" , __FUNCTION__ )) && (dbgtext ("ipasam_get_trusted_domain_by_sid called for sid %s\n" , sid_str)) ); |
| 2458 | |
| 2459 | ok = get_trusted_domain_by_sid_int(ipasam_state, mem_ctx, sid_str, |
| 2460 | &entry); |
| 2461 | talloc_free(sid_str)_talloc_free(sid_str, "ipa_sam.c" ":" "2461"); |
| 2462 | if (!ok) { |
| 2463 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2464 | } |
| 2465 | if (entry == NULL((void*)0)) { |
| 2466 | DEBUG(5, ("ipasam_get_trusted_domain_by_sid: no trusted domain "(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "2467", __FUNCTION__ )) && (dbgtext ("ipasam_get_trusted_domain_by_sid: no trusted domain " "with sid: %s\n", sid_str)) ) |
| 2467 | "with sid: %s\n", sid_str))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "2467", __FUNCTION__ )) && (dbgtext ("ipasam_get_trusted_domain_by_sid: no trusted domain " "with sid: %s\n", sid_str)) ); |
| 2468 | return NT_STATUS_NO_SUCH_DOMAIN((NTSTATUS) { 0xc00000df }); |
| 2469 | } |
| 2470 | |
| 2471 | ok = fill_pdb_trusted_domain(mem_ctx, ipasam_state, entry, td); |
| 2472 | if (!ok) { |
| 2473 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2474 | } |
| 2475 | |
| 2476 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 2477 | } |
| 2478 | |
| 2479 | static bool_Bool smbldap_make_mod_uint32_t(LDAP *ldap_struct, LDAPMessage *entry, |
| 2480 | LDAPMod ***mods, const char *attribute, |
| 2481 | const uint32_t val) |
| 2482 | { |
| 2483 | char *dummy; |
| 2484 | |
| 2485 | dummy = talloc_asprintf(NULL((void*)0), "%lu", (unsigned long) val); |
| 2486 | if (dummy == NULL((void*)0)) { |
| 2487 | return false0; |
| 2488 | } |
| 2489 | smbldap_make_mod(ldap_struct, entry, mods, attribute, dummy); |
| 2490 | TALLOC_FREE(dummy)do { if (dummy != ((void*)0)) { _talloc_free(dummy, "ipa_sam.c" ":" "2490"); dummy=((void*)0); } } while(0); |
| 2491 | |
| 2492 | return true1; |
| 2493 | } |
| 2494 | |
| 2495 | static NTSTATUS get_trust_pwd(TALLOC_CTX *mem_ctx, const DATA_BLOB *auth_blob, |
| 2496 | char **pwd, NTTIME *last_update) |
| 2497 | { |
| 2498 | NTSTATUS status; |
| 2499 | struct trustAuthInOutBlob iopw; |
| 2500 | enum ndr_err_code ndr_err; |
| 2501 | TALLOC_CTX *tmp_ctx; |
| 2502 | char *trustpw; |
| 2503 | size_t converted_size; |
| 2504 | |
| 2505 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "2505"); |
| 2506 | if (tmp_ctx == NULL((void*)0)) { |
| 2507 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2508 | } |
| 2509 | |
| 2510 | ndr_err = ndr_pull_struct_blob(auth_blob, tmp_ctx, &iopw, |
| 2511 | (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); |
| 2512 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)(ndr_err == NDR_ERR_SUCCESS)) { |
| 2513 | status = NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 2514 | goto done; |
| 2515 | } |
| 2516 | |
| 2517 | if (iopw.count != 0 && iopw.current.count != 0 && |
| 2518 | iopw.current.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) { |
| 2519 | if (pwd != NULL((void*)0)) { |
| 2520 | if (!convert_string_talloc(tmp_ctx, CH_UTF16, CH_UNIX, |
| 2521 | iopw.current.array[0].AuthInfo.clear.password, |
| 2522 | iopw.current.array[0].AuthInfo.clear.size, |
| 2523 | &trustpw, &converted_size)) { |
| 2524 | |
| 2525 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2526 | goto done; |
| 2527 | } |
| 2528 | |
| 2529 | *pwd = talloc_strndup(mem_ctx, trustpw, converted_size); |
| 2530 | if (*pwd == NULL((void*)0)) { |
| 2531 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2532 | goto done; |
| 2533 | } |
| 2534 | } |
| 2535 | |
| 2536 | if (last_update != NULL((void*)0)) { |
| 2537 | *last_update = iopw.current.array[0].LastUpdateTime; |
| 2538 | } |
| 2539 | } else { |
| 2540 | status = NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 2541 | goto done; |
| 2542 | } |
| 2543 | |
| 2544 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 2545 | |
| 2546 | done: |
| 2547 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "2547"); |
| 2548 | return status; |
| 2549 | } |
| 2550 | |
| 2551 | static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods, |
| 2552 | const char* domain, |
| 2553 | const struct pdb_trusted_domain *td) |
| 2554 | { |
| 2555 | struct ipasam_private *ipasam_state = |
| 2556 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "2556"); |
| 2557 | LDAPMessage *entry = NULL((void*)0); |
| 2558 | LDAPMod **mods; |
| 2559 | bool_Bool res; |
| 2560 | char *trusted_dn = NULL((void*)0); |
| 2561 | int ret, i, count; |
| 2562 | NTSTATUS status; |
| 2563 | TALLOC_CTX *tmp_ctx; |
| 2564 | char *trustpw_incoming, *trustpw_outgoing; |
| 2565 | char *sid, *tda_name; |
| 2566 | char **in_blacklist = NULL((void*)0); |
| 2567 | char **out_blacklist = NULL((void*)0); |
| 2568 | uint32_t enctypes, trust_offset; |
| 2569 | |
| 2570 | DEBUG(10, ("ipasam_set_trusted_domain called for domain %s\n", domain))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "2570" , __FUNCTION__ )) && (dbgtext ("ipasam_set_trusted_domain called for domain %s\n" , domain)) ); |
| 2571 | |
| 2572 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "2572"); |
| 2573 | if (tmp_ctx == NULL((void*)0)) { |
| 2574 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2575 | } |
| 2576 | |
| 2577 | res = get_trusted_domain_by_name_int(ipasam_state, tmp_ctx, domain, |
| 2578 | &entry); |
| 2579 | if (!res) { |
| 2580 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2581 | goto done; |
| 2582 | } |
| 2583 | |
| 2584 | mods = NULL((void*)0); |
| 2585 | if (entry == NULL((void*)0)) { |
| 2586 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, "objectClass", |
| 2587 | LDAP_OBJ_TRUSTED_DOMAIN"ipaNTTrustedDomain"); |
| 2588 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, "objectClass", |
| 2589 | LDAP_OBJ_ID_OBJECT"ipaIDobject"); |
| 2590 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, "objectClass", |
| 2591 | LDAP_OBJ_POSIXACCOUNT"posixAccount"); |
| 2592 | } |
| 2593 | |
| 2594 | if (entry != NULL((void*)0)) { |
| 2595 | sid = get_single_attribute(tmp_ctx, priv2ld(ipasam_state), entry, |
| 2596 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 2597 | } |
| 2598 | if (entry == NULL((void*)0) || sid == NULL((void*)0)) { |
| 2599 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2600 | LDAP_ATTRIBUTE_UIDNUMBER"uidnumber", IPA_MAGIC_ID_STR"-1"); |
| 2601 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2602 | LDAP_ATTRIBUTE_GIDNUMBER"gidnumber", |
| 2603 | ipasam_state->fallback_primary_group_gid_str); |
| 2604 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2605 | LDAP_ATTRIBUTE_HOMEDIRECTORY"homeDirectory", |
| 2606 | "/dev/null"); |
| 2607 | } |
| 2608 | |
| 2609 | if (td->netbios_name != NULL((void*)0)) { |
| 2610 | tda_name = talloc_asprintf(tmp_ctx, "%s$", td->netbios_name); |
| 2611 | if (!tda_name) { |
| 2612 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2613 | goto done; |
| 2614 | } |
| 2615 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2616 | LDAP_ATTRIBUTE_FLAT_NAME"ipaNTFlatName", |
| 2617 | td->netbios_name); |
| 2618 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2619 | LDAP_ATTRIBUTE_UID"uid", |
| 2620 | tda_name); |
| 2621 | } |
| 2622 | |
| 2623 | if (td->domain_name != NULL((void*)0)) { |
| 2624 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2625 | LDAP_ATTRIBUTE_TRUST_PARTNER"ipaNTTrustPartner", |
| 2626 | td->domain_name); |
| 2627 | } |
| 2628 | |
| 2629 | if (!is_null_sid(&td->security_identifier)) { |
| 2630 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2631 | LDAP_ATTRIBUTE_TRUST_SID"ipaNTTrustedDomainSID", |
| 2632 | sid_talloc_string(ipasam_state->idmap_ctx, |
| 2633 | tmp_ctx, &td->security_identifier)); |
| 2634 | } |
| 2635 | |
| 2636 | if (td->trust_type != 0) { |
| 2637 | res = smbldap_make_mod_uint32_t(priv2ld(ipasam_state), entry, |
| 2638 | &mods, LDAP_ATTRIBUTE_TRUST_TYPE"ipaNTTrustType", |
| 2639 | td->trust_type); |
| 2640 | if (!res) { |
| 2641 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2642 | goto done; |
| 2643 | } |
| 2644 | } |
| 2645 | |
| 2646 | if (td->trust_attributes != 0) { |
| 2647 | res = smbldap_make_mod_uint32_t(priv2ld(ipasam_state), entry, |
| 2648 | &mods, |
| 2649 | LDAP_ATTRIBUTE_TRUST_ATTRIBUTES"ipaNTTrustAttributes", |
| 2650 | td->trust_attributes); |
| 2651 | if (!res) { |
| 2652 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2653 | goto done; |
| 2654 | } |
| 2655 | } |
| 2656 | |
| 2657 | if (td->trust_direction != 0) { |
| 2658 | res = smbldap_make_mod_uint32_t(priv2ld(ipasam_state), entry, |
| 2659 | &mods, |
| 2660 | LDAP_ATTRIBUTE_TRUST_DIRECTION"ipaNTTrustDirection", |
| 2661 | td->trust_direction); |
| 2662 | if (!res) { |
| 2663 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2664 | goto done; |
| 2665 | } |
| 2666 | } |
| 2667 | |
| 2668 | trust_offset = 0; |
| 2669 | if (td->trust_posix_offset != NULL((void*)0)) { |
| 2670 | trust_offset = *td->trust_posix_offset; |
| 2671 | } |
| 2672 | |
| 2673 | res = smbldap_make_mod_uint32_t(priv2ld(ipasam_state), entry, |
| 2674 | &mods, |
| 2675 | LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET"ipaNTTrustPosixOffset", |
| 2676 | trust_offset); |
| 2677 | if (!res) { |
| 2678 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2679 | goto done; |
| 2680 | } |
| 2681 | |
| 2682 | enctypes = ipasam_state->supported_enctypes; |
| 2683 | if (td->supported_enc_type != NULL((void*)0)) { |
| 2684 | enctypes = *td->supported_enc_type; |
| 2685 | } |
| 2686 | |
| 2687 | res = smbldap_make_mod_uint32_t(priv2ld(ipasam_state), entry, |
| 2688 | &mods, |
| 2689 | LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE"ipaNTSupportedEncryptionTypes", |
| 2690 | enctypes); |
| 2691 | if (!res) { |
| 2692 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2693 | goto done; |
| 2694 | } |
| 2695 | |
| 2696 | if (td->trust_auth_outgoing.data != NULL((void*)0)) { |
| 2697 | smbldap_make_mod_blob(priv2ld(ipasam_state), entry, &mods, |
| 2698 | LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING"ipaNTTrustAuthOutgoing", |
| 2699 | &td->trust_auth_outgoing); |
| 2700 | } |
| 2701 | |
| 2702 | if (td->trust_auth_incoming.data != NULL((void*)0)) { |
| 2703 | smbldap_make_mod_blob(priv2ld(ipasam_state), entry, &mods, |
| 2704 | LDAP_ATTRIBUTE_TRUST_AUTH_INCOMING"ipaNTTrustAuthIncoming", |
| 2705 | &td->trust_auth_incoming); |
| 2706 | } |
| 2707 | |
| 2708 | if (td->trust_forest_trust_info.data != NULL((void*)0)) { |
| 2709 | smbldap_make_mod_blob(priv2ld(ipasam_state), entry, &mods, |
| 2710 | LDAP_ATTRIBUTE_TRUST_FOREST_TRUST_INFO"ipaNTTrustForestTrustInfo", |
| 2711 | &td->trust_forest_trust_info); |
| 2712 | } |
| 2713 | |
| 2714 | |
| 2715 | /* Only add default blacklists for incoming and outgoing SIDs but don't modify existing ones */ |
| 2716 | in_blacklist = get_attribute_values(tmp_ctx, priv2ld(ipasam_state), entry, |
| 2717 | LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING"ipaNTSIDBlacklistIncoming", &count); |
| 2718 | out_blacklist = get_attribute_values(tmp_ctx, priv2ld(ipasam_state), entry, |
| 2719 | LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING"ipaNTSIDBlacklistOutgoing", &count); |
| 2720 | |
| 2721 | for (i = 0; ipa_mspac_well_known_sids[i]; i++) { |
| 2722 | if (in_blacklist == NULL((void*)0)) { |
| 2723 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2724 | LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING"ipaNTSIDBlacklistIncoming", |
| 2725 | ipa_mspac_well_known_sids[i]); |
| 2726 | } |
| 2727 | if (out_blacklist == NULL((void*)0)) { |
| 2728 | smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, |
| 2729 | LDAP_ATTRIBUTE_SID_BLACKLIST_OUTGOING"ipaNTSIDBlacklistOutgoing", |
| 2730 | ipa_mspac_well_known_sids[i]); |
| 2731 | } |
| 2732 | } |
| 2733 | |
| 2734 | smbldap_talloc_autofree_ldapmod(tmp_ctx, mods); |
| 2735 | |
| 2736 | if (mods != NULL((void*)0)) { |
| 2737 | trusted_dn = trusted_domain_dn(tmp_ctx, ipasam_state, domain); |
| 2738 | if (trusted_dn == NULL((void*)0)) { |
| 2739 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2740 | goto done; |
| 2741 | } |
| 2742 | |
| 2743 | if (entry == NULL((void*)0)) { |
| 2744 | ret = smbldap_add(ipasam_state->ldap_state, trusted_dn, mods); |
| 2745 | } else { |
| 2746 | ret = smbldap_modify(ipasam_state->ldap_state, trusted_dn, mods); |
| 2747 | } |
| 2748 | if (ret != LDAP_SUCCESS0x00) { |
| 2749 | DEBUG(1, ("error writing trusted domain data!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2749", __FUNCTION__ )) && (dbgtext ("error writing trusted domain data!\n" )) ); |
| 2750 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2751 | goto done; |
| 2752 | } |
| 2753 | } |
| 2754 | |
| 2755 | if (entry == NULL((void*)0)) { /* FIXME: allow password updates here */ |
| 2756 | status = get_trust_pwd(tmp_ctx, &td->trust_auth_incoming, |
| 2757 | &trustpw_incoming, NULL((void*)0)); |
| 2758 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 2759 | goto done; |
| 2760 | } |
| 2761 | status = get_trust_pwd(tmp_ctx, &td->trust_auth_outgoing, |
| 2762 | &trustpw_outgoing, NULL((void*)0)); |
| 2763 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 2764 | goto done; |
| 2765 | } |
| 2766 | res = set_cross_realm_princs(ipasam_state, td->domain_name, td->netbios_name, |
| 2767 | trustpw_incoming, trustpw_outgoing, |
| 2768 | td->trust_direction); |
| 2769 | { |
| 2770 | /* Replace memset() use by an explicit loop to avoid |
| 2771 | * both compile time and link time optimisations. |
| 2772 | * We could have used memset_s() from C++11 but it is |
| 2773 | * currently not implemented by GCC or glibc. |
| 2774 | */ |
| 2775 | volatile char *p = (void *) trustpw_incoming; |
| 2776 | volatile char *q = (void *) trustpw_outgoing; |
| 2777 | size_t plen = strlen(trustpw_incoming); |
| 2778 | size_t qlen = strlen(trustpw_outgoing); |
| 2779 | |
| 2780 | while (plen--) { |
| 2781 | *p++ = '\0'; |
| 2782 | } |
| 2783 | |
| 2784 | while (qlen--) { |
| 2785 | *q++ = '\0'; |
| 2786 | } |
| 2787 | } |
| 2788 | |
| 2789 | if (!res) { |
| 2790 | DEBUG(1, ("error writing cross realm principals!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2790", __FUNCTION__ )) && (dbgtext ("error writing cross realm principals!\n" )) ); |
| 2791 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2792 | goto done; |
| 2793 | } |
| 2794 | } |
| 2795 | |
| 2796 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 2797 | done: |
| 2798 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "2798"); |
| 2799 | return status; |
| 2800 | } |
| 2801 | |
| 2802 | static int delete_subtree(struct ipasam_private *ipasam_state, char* dn) |
| 2803 | { |
| 2804 | LDAP *state = priv2ld(ipasam_state); |
| 2805 | int rc; |
| 2806 | char *filter = NULL((void*)0); |
| 2807 | int scope = LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002); |
| 2808 | LDAPMessage *result = NULL((void*)0); |
| 2809 | LDAPMessage *entry = NULL((void*)0); |
| 2810 | char *entry_dn = NULL((void*)0); |
| 2811 | |
| 2812 | /* use 'dn' for a temporary talloc context */ |
| 2813 | filter = talloc_asprintf(dn, "(objectClass=*)"); |
| 2814 | if (filter == NULL((void*)0)) { |
| 2815 | return LDAP_NO_MEMORY(-10); |
| 2816 | } |
| 2817 | |
| 2818 | rc = smbldap_search(ipasam_state->ldap_state, dn, scope, filter, NULL((void*)0), 0, &result); |
| 2819 | TALLOC_FREE(filter)do { if (filter != ((void*)0)) { _talloc_free(filter, "ipa_sam.c" ":" "2819"); filter=((void*)0); } } while(0); |
| 2820 | |
| 2821 | if (rc != LDAP_SUCCESS0x00) { |
| 2822 | return rc; |
| 2823 | } |
| 2824 | |
| 2825 | if (result == NULL((void*)0)) { |
| 2826 | return LDAP_NO_MEMORY(-10); |
| 2827 | } |
| 2828 | |
| 2829 | smbldap_talloc_autofree_ldapmsg(dn, result); |
| 2830 | |
| 2831 | for (entry = ldap_first_entry(state, result); |
| 2832 | entry != NULL((void*)0); |
| 2833 | entry = ldap_next_entry(state, entry)) { |
| 2834 | entry_dn = get_dn(dn, state, entry); |
| 2835 | /* remove child entries */ |
| 2836 | if ((entry_dn != NULL((void*)0)) && (strcmp(entry_dn, dn) != 0)) { |
| 2837 | rc = smbldap_delete(ipasam_state->ldap_state, entry_dn); |
| 2838 | if (rc != LDAP_SUCCESS0x00) { |
| 2839 | return rc; |
| 2840 | } |
| 2841 | } |
| 2842 | } |
| 2843 | rc = smbldap_delete(ipasam_state->ldap_state, dn); |
| 2844 | |
| 2845 | /* caller will destroy dn */ |
| 2846 | return rc; |
| 2847 | } |
| 2848 | |
| 2849 | static NTSTATUS ipasam_del_trusted_domain(struct pdb_methods *methods, |
| 2850 | const char *domain) |
| 2851 | { |
| 2852 | int ret; |
| 2853 | struct ipasam_private *ipasam_state = |
| 2854 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "2854"); |
| 2855 | LDAPMessage *entry = NULL((void*)0); |
| 2856 | char *dn; |
| 2857 | const char *domain_name, *flat_name; |
| 2858 | TALLOC_CTX *tmp_ctx; |
| 2859 | NTSTATUS status; |
| 2860 | |
| 2861 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "2861"); |
| 2862 | if (tmp_ctx == NULL((void*)0)) { |
| 2863 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2864 | } |
| 2865 | |
| 2866 | if (!get_trusted_domain_by_name_int(ipasam_state, tmp_ctx, domain, |
| 2867 | &entry)) { |
| 2868 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2869 | goto done; |
| 2870 | } |
| 2871 | |
| 2872 | if (entry == NULL((void*)0)) { |
| 2873 | DEBUG(5, ("ipasam_del_trusted_domain: no such trusted domain: "(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "2874", __FUNCTION__ )) && (dbgtext ("ipasam_del_trusted_domain: no such trusted domain: " "%s\n", domain)) ) |
| 2874 | "%s\n", domain))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "2874", __FUNCTION__ )) && (dbgtext ("ipasam_del_trusted_domain: no such trusted domain: " "%s\n", domain)) ); |
| 2875 | status = NT_STATUS_NO_SUCH_DOMAIN((NTSTATUS) { 0xc00000df }); |
| 2876 | goto done; |
| 2877 | } |
| 2878 | |
| 2879 | dn = get_dn(tmp_ctx, priv2ld(ipasam_state), entry); |
| 2880 | if (dn == NULL((void*)0)) { |
| 2881 | DEBUG(0,("ipasam_del_trusted_domain: Out of memory!\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "2881", __FUNCTION__ )) && (dbgtext ("ipasam_del_trusted_domain: Out of memory!\n" )) ); |
| 2882 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2883 | goto done; |
| 2884 | } |
| 2885 | |
| 2886 | domain_name = get_single_attribute(tmp_ctx, priv2ld(ipasam_state), entry, |
| 2887 | LDAP_ATTRIBUTE_TRUST_PARTNER"ipaNTTrustPartner"); |
| 2888 | if (domain_name == NULL((void*)0)) { |
| 2889 | DEBUG(1, ("Attribute %s not present.\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2890", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTTrustPartner" )) ) |
| 2890 | LDAP_ATTRIBUTE_TRUST_PARTNER))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2890", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTTrustPartner" )) ); |
| 2891 | status = NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 2892 | goto done; |
| 2893 | } |
| 2894 | |
| 2895 | flat_name = get_single_attribute(tmp_ctx, priv2ld(ipasam_state), entry, |
| 2896 | LDAP_ATTRIBUTE_FLAT_NAME"ipaNTFlatName"); |
| 2897 | if (flat_name == NULL((void*)0)) { |
| 2898 | DEBUG(1, ("Attribute %s not present.\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2899", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTFlatName" )) ) |
| 2899 | LDAP_ATTRIBUTE_FLAT_NAME))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2899", __FUNCTION__ )) && (dbgtext ("Attribute %s not present.\n", "ipaNTFlatName" )) ); |
| 2900 | status = NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 2901 | goto done; |
| 2902 | } |
| 2903 | |
| 2904 | |
| 2905 | if (!del_cross_realm_princs(ipasam_state, domain_name, flat_name)) { |
| 2906 | DEBUG(1, ("error deleting cross realm principals!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2906", __FUNCTION__ )) && (dbgtext ("error deleting cross realm principals!\n" )) ); |
| 2907 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2908 | goto done; |
| 2909 | } |
| 2910 | |
| 2911 | ret = smbldap_delete(ipasam_state->ldap_state, dn); |
| 2912 | if (ret == LDAP_NOT_ALLOWED_ON_NONLEAF0x42) { |
| 2913 | /* delete_subtree will use 'dn' as temporary context too */ |
| 2914 | ret = delete_subtree(ipasam_state, dn); |
| 2915 | } |
| 2916 | |
| 2917 | if (ret != LDAP_SUCCESS0x00) { |
| 2918 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2919 | goto done; |
| 2920 | } |
| 2921 | |
| 2922 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 2923 | done: |
| 2924 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "2924"); |
| 2925 | return status; |
| 2926 | } |
| 2927 | |
| 2928 | static NTSTATUS ipasam_enum_trusted_domains(struct pdb_methods *methods, |
| 2929 | TALLOC_CTX *mem_ctx, |
| 2930 | uint32_t *num_domains, |
| 2931 | struct pdb_trusted_domain ***domains) |
| 2932 | { |
| 2933 | int rc; |
| 2934 | struct ipasam_private *ipasam_state = |
| 2935 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "2935"); |
| 2936 | char *filter = NULL((void*)0); |
| 2937 | int scope = LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002); |
| 2938 | LDAPMessage *result = NULL((void*)0); |
| 2939 | LDAPMessage *entry = NULL((void*)0); |
| 2940 | struct pdb_trusted_domain **tmp; |
| 2941 | |
| 2942 | filter = talloc_asprintf(mem_ctx, "(objectClass=%s)", |
| 2943 | LDAP_OBJ_TRUSTED_DOMAIN"ipaNTTrustedDomain"); |
| 2944 | if (filter == NULL((void*)0)) { |
| 2945 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2946 | } |
| 2947 | |
| 2948 | rc = smbldap_search(ipasam_state->ldap_state, |
| 2949 | ipasam_state->trust_dn, |
| 2950 | scope, filter, NULL((void*)0), 0, &result); |
| 2951 | TALLOC_FREE(filter)do { if (filter != ((void*)0)) { _talloc_free(filter, "ipa_sam.c" ":" "2951"); filter=((void*)0); } } while(0); |
| 2952 | |
| 2953 | if (result != NULL((void*)0)) { |
| 2954 | smbldap_talloc_autofree_ldapmsg(mem_ctx, result); |
| 2955 | } |
| 2956 | |
| 2957 | if (rc == LDAP_NO_SUCH_OBJECT0x20) { |
| 2958 | *num_domains = 0; |
| 2959 | *domains = NULL((void*)0); |
| 2960 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 2961 | } |
| 2962 | |
| 2963 | if (rc != LDAP_SUCCESS0x00) { |
| 2964 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2965 | } |
| 2966 | |
| 2967 | *num_domains = 0; |
| 2968 | if (!(*domains = talloc_array(mem_ctx, struct pdb_trusted_domain *, 1)(struct pdb_trusted_domain * *)_talloc_array(mem_ctx, sizeof( struct pdb_trusted_domain *), 1, "struct pdb_trusted_domain *" ))) { |
| 2969 | DEBUG(1, ("talloc failed\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "2969", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 2970 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2971 | } |
| 2972 | |
| 2973 | for (entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 2974 | entry != NULL((void*)0); |
| 2975 | entry = ldap_next_entry(priv2ld(ipasam_state), entry)) |
| 2976 | { |
| 2977 | struct pdb_trusted_domain *dom_info; |
| 2978 | |
| 2979 | if (!fill_pdb_trusted_domain(*domains, ipasam_state, entry, |
| 2980 | &dom_info)) { |
| 2981 | talloc_free(*domains)_talloc_free(*domains, "ipa_sam.c" ":" "2981"); |
| 2982 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 2983 | } |
| 2984 | |
| 2985 | tmp = talloc_realloc(*domains, *domains,(struct pdb_trusted_domain * *)_talloc_realloc_array(*domains , *domains, sizeof(struct pdb_trusted_domain *), (*(num_domains ))+1, "struct pdb_trusted_domain *") |
| 2986 | struct pdb_trusted_domain *,(struct pdb_trusted_domain * *)_talloc_realloc_array(*domains , *domains, sizeof(struct pdb_trusted_domain *), (*(num_domains ))+1, "struct pdb_trusted_domain *") |
| 2987 | (*(num_domains))+1)(struct pdb_trusted_domain * *)_talloc_realloc_array(*domains , *domains, sizeof(struct pdb_trusted_domain *), (*(num_domains ))+1, "struct pdb_trusted_domain *"); |
| 2988 | if (tmp == NULL((void*)0)) { |
| 2989 | talloc_free(*domains)_talloc_free(*domains, "ipa_sam.c" ":" "2989"); |
| 2990 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 2991 | } |
| 2992 | *domains = tmp; |
| 2993 | (*(domains))[*(num_domains)] = dom_info; |
| 2994 | (*(num_domains)) += 1; |
| 2995 | } |
| 2996 | |
| 2997 | DEBUG(5, ("ipasam_enum_trusted_domains: got %d domains\n", *num_domains))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "2997", __FUNCTION__ )) && (dbgtext ("ipasam_enum_trusted_domains: got %d domains\n" , *num_domains)) ); |
| 2998 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 2999 | } |
| 3000 | |
| 3001 | static NTSTATUS ipasam_enum_trusteddoms(struct pdb_methods *methods, |
| 3002 | TALLOC_CTX *mem_ctx, |
| 3003 | uint32_t *num_domains, |
| 3004 | struct trustdom_info ***domains) |
| 3005 | { |
| 3006 | NTSTATUS status; |
| 3007 | struct pdb_trusted_domain **td; |
| 3008 | int i; |
| 3009 | |
| 3010 | status = ipasam_enum_trusted_domains(methods, mem_ctx, |
| 3011 | num_domains, &td); |
| 3012 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 3013 | return status; |
| 3014 | } |
| 3015 | |
| 3016 | if (*num_domains == 0) { |
| 3017 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 3018 | } |
| 3019 | |
| 3020 | if (!(*domains = talloc_array(mem_ctx, struct trustdom_info *,(struct trustdom_info * *)_talloc_array(mem_ctx, sizeof(struct trustdom_info *), *num_domains, "struct trustdom_info *") |
| 3021 | *num_domains)(struct trustdom_info * *)_talloc_array(mem_ctx, sizeof(struct trustdom_info *), *num_domains, "struct trustdom_info *"))) { |
| 3022 | DEBUG(1, ("talloc failed\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3022", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 3023 | goto fail; |
| 3024 | } |
| 3025 | |
| 3026 | for (i = 0; i < *num_domains; i++) { |
| 3027 | struct trustdom_info *dom_info; |
| 3028 | |
| 3029 | dom_info = talloc(*domains, struct trustdom_info)(struct trustdom_info *)talloc_named_const(*domains, sizeof(struct trustdom_info), "struct trustdom_info"); |
| 3030 | if (dom_info == NULL((void*)0)) { |
| 3031 | DEBUG(1, ("talloc failed\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3031", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 3032 | goto fail; |
| 3033 | } |
| 3034 | |
| 3035 | dom_info->name = talloc_steal(mem_ctx, td[i]->netbios_name)({ __typeof__(td[i]->netbios_name) __talloc_steal_ret = (__typeof__ (td[i]->netbios_name))_talloc_steal_loc((mem_ctx),(td[i]-> netbios_name), "ipa_sam.c" ":" "3035"); __talloc_steal_ret; } ); |
| 3036 | sid_copy(&dom_info->sid, &td[i]->security_identifier); |
| 3037 | |
| 3038 | (*domains)[i] = dom_info; |
| 3039 | } |
| 3040 | |
| 3041 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 3042 | |
| 3043 | fail: |
| 3044 | talloc_free(td)_talloc_free(td, "ipa_sam.c" ":" "3044"); |
| 3045 | talloc_free(*domains)_talloc_free(*domains, "ipa_sam.c" ":" "3045"); |
| 3046 | |
| 3047 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3048 | } |
| 3049 | |
| 3050 | static uint32_t pdb_ipasam_capabilities(struct pdb_methods *methods) |
| 3051 | { |
| 3052 | return PDB_CAP_STORE_RIDS0x0001 | PDB_CAP_ADS0x0002 | PDB_CAP_TRUSTED_DOMAINS_EX0x0004; |
| 3053 | } |
| 3054 | |
| 3055 | static bool_Bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td, |
| 3056 | LDAPMessage *entry, |
| 3057 | struct ipasam_private *ipasam_state) |
| 3058 | { |
| 3059 | NTSTATUS status; |
| 3060 | struct dom_sid *u_sid; |
| 3061 | struct dom_sid *g_sid; |
| 3062 | char *name; |
| 3063 | char *trustpw = NULL((void*)0); |
| 3064 | uint8_t nt_key[16]; |
| 3065 | bool_Bool res; |
| 3066 | char *sid_str; |
| 3067 | enum idmap_error_code err; |
| 3068 | |
| 3069 | if (!pdb_set_acct_ctrl(user, ACB_DOMTRUST( 0x00000040 ) | ACB_TRUSTED_FOR_DELEGATION( 0x00002000 ), |
| 3070 | PDB_SET)) { |
| 3071 | return false0; |
| 3072 | } |
| 3073 | |
| 3074 | if (!pdb_set_domain(user, ipasam_state->domain_name, PDB_DEFAULT)) { |
| 3075 | return false0; |
| 3076 | } |
| 3077 | |
| 3078 | name = talloc_asprintf(user, "%s$", td->netbios_name); |
| 3079 | if (name == NULL((void*)0)) { |
| 3080 | return false0; |
| 3081 | } |
| 3082 | |
| 3083 | if (!pdb_set_username(user, name, PDB_SET)) { |
| 3084 | return false0; |
| 3085 | } |
| 3086 | |
| 3087 | if (!pdb_set_nt_username(user, name, PDB_SET)) { |
| 3088 | return false0; |
| 3089 | } |
| 3090 | |
| 3091 | sid_str = get_single_attribute(user, priv2ld(ipasam_state), entry, |
| 3092 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 3093 | if (sid_str == NULL((void*)0)) { |
| 3094 | DEBUG(5, ("Missing SID for trusted domain object.\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3094", __FUNCTION__ )) && (dbgtext ("Missing SID for trusted domain object.\n" )) ); |
| 3095 | return false0; |
| 3096 | } |
| 3097 | |
| 3098 | err = sss_idmap_sid_to_smb_sid(ipasam_state->idmap_ctx, |
| 3099 | sid_str, &u_sid); |
| 3100 | if (err != IDMAP_SUCCESS) { |
| 3101 | DEBUG(10, ("Could not convert string %s to sid.\n", sid_str))(void)( ((10) <= 1000) && (debuglevel_get_class(0) >= (10)) && (dbghdrclass( 10, 0, "ipa_sam.c" ":" "3101" , __FUNCTION__ )) && (dbgtext ("Could not convert string %s to sid.\n" , sid_str)) ); |
| 3102 | talloc_free(sid_str)_talloc_free(sid_str, "ipa_sam.c" ":" "3102"); |
| 3103 | return false0; |
| 3104 | } |
| 3105 | talloc_free(sid_str)_talloc_free(sid_str, "ipa_sam.c" ":" "3105"); |
| 3106 | |
| 3107 | if (!pdb_set_user_sid(user, u_sid, PDB_SET)) { |
| 3108 | talloc_free(u_sid)_talloc_free(u_sid, "ipa_sam.c" ":" "3108"); |
| 3109 | return false0; |
| 3110 | } |
| 3111 | talloc_free(u_sid)_talloc_free(u_sid, "ipa_sam.c" ":" "3111"); |
| 3112 | |
| 3113 | g_sid = &ipasam_state->fallback_primary_group; |
| 3114 | if (!pdb_set_group_sid(user, g_sid, PDB_SET)) { |
| 3115 | return false0; |
| 3116 | } |
| 3117 | |
| 3118 | status = get_trust_pwd(user, &td->trust_auth_incoming, &trustpw, NULL((void*)0)); |
| 3119 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 3120 | return false0; |
| 3121 | } |
| 3122 | |
| 3123 | if (!E_md4hash(trustpw, nt_key)) { |
| 3124 | res = false0; |
| 3125 | goto done; |
| 3126 | } |
| 3127 | |
| 3128 | if (!pdb_set_nt_passwd(user, nt_key, PDB_SET)) { |
| 3129 | res = false0; |
| 3130 | goto done; |
| 3131 | } |
| 3132 | |
| 3133 | res = true1; |
| 3134 | done: |
| 3135 | if (trustpw != NULL((void*)0)) { |
| 3136 | memset(trustpw, 0, strlen(trustpw)); |
| 3137 | talloc_free(trustpw)_talloc_free(trustpw, "ipa_sam.c" ":" "3137"); |
| 3138 | } |
| 3139 | |
| 3140 | return res; |
| 3141 | } |
| 3142 | |
| 3143 | static bool_Bool ipasam_nthash_retrieve(struct ipasam_private *ipasam_state, |
| 3144 | TALLOC_CTX *mem_ctx, |
| 3145 | char *entry_dn, |
| 3146 | DATA_BLOB *nthash) |
| 3147 | { |
| 3148 | int ret; |
| 3149 | bool_Bool retval; |
| 3150 | LDAPMessage *result; |
| 3151 | LDAPMessage *entry = NULL((void*)0); |
| 3152 | int count; |
| 3153 | struct smbldap_state *ldap_state = ipasam_state->ldap_state; |
| 3154 | const char *attr_list[] = { |
| 3155 | LDAP_ATTRIBUTE_NTHASH"ipaNTHash", |
| 3156 | NULL((void*)0) |
| 3157 | }; |
| 3158 | |
| 3159 | ret = smbldap_search(ldap_state, entry_dn, |
| 3160 | LDAP_SCOPE_BASE((ber_int_t) 0x0000), "(objectclass=*)", attr_list, 0, |
| 3161 | &result); |
| 3162 | if (ret != LDAP_SUCCESS0x00) { |
| 3163 | DEBUG(1, ("Failed to get NT hash: %s\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3164", __FUNCTION__ )) && (dbgtext ("Failed to get NT hash: %s\n", ldap_err2string (ret))) ) |
| 3164 | ldap_err2string (ret)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3164", __FUNCTION__ )) && (dbgtext ("Failed to get NT hash: %s\n", ldap_err2string (ret))) ); |
| 3165 | return false0; |
| 3166 | } |
| 3167 | |
| 3168 | count = ldap_count_entries(priv2ld(ipasam_state), result); |
| 3169 | |
| 3170 | if (count != 1) { |
| 3171 | DEBUG(1, ("Unexpected number of results [%d] for NT hash "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3172", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for NT hash " "of the single entry search.\n", count)) ) |
| 3172 | "of the single entry search.\n", count))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3172", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for NT hash " "of the single entry search.\n", count)) ); |
| 3173 | ldap_msgfree(result); |
| 3174 | return false0; |
| 3175 | } |
| 3176 | |
| 3177 | entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 3178 | if (entry == NULL((void*)0)) { |
| 3179 | DEBUG(0, ("Could not get entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3179", __FUNCTION__ )) && (dbgtext ("Could not get entry\n")) ); |
| 3180 | ldap_msgfree(result); |
| 3181 | return false0; |
| 3182 | } |
| 3183 | |
| 3184 | retval = smbldap_talloc_single_blob(mem_ctx, |
| 3185 | priv2ld(ipasam_state), |
| 3186 | entry, LDAP_ATTRIBUTE_NTHASH"ipaNTHash", |
| 3187 | nthash); |
| 3188 | ldap_msgfree(result); |
| 3189 | return retval; |
| 3190 | } |
| 3191 | |
| 3192 | static bool_Bool ipasam_nthash_regen(struct ipasam_private *ipasam_state, |
| 3193 | TALLOC_CTX *mem_ctx, |
| 3194 | char * entry_dn) |
| 3195 | { |
| 3196 | LDAPMod **mods = NULL((void*)0); |
| 3197 | int ret; |
| 3198 | |
| 3199 | smbldap_set_mod(&mods, LDAP_MOD_ADD(0x0000), LDAP_ATTRIBUTE_NTHASH"ipaNTHash", "MagicRegen"); |
| 3200 | smbldap_talloc_autofree_ldapmod(mem_ctx, mods); |
| 3201 | |
| 3202 | ret = smbldap_modify(ipasam_state->ldap_state, entry_dn, mods); |
| 3203 | if (ret != LDAP_SUCCESS0x00) { |
| 3204 | DEBUG(5, ("ipasam: attempt to regen ipaNTHash failed\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3204", __FUNCTION__ )) && (dbgtext ("ipasam: attempt to regen ipaNTHash failed\n" )) ); |
| 3205 | } |
| 3206 | return (ret == LDAP_SUCCESS0x00); |
| 3207 | } |
| 3208 | |
| 3209 | static int ipasam_get_sid_by_gid(struct ipasam_private *ipasam_state, |
| 3210 | uint32_t gid, |
| 3211 | struct dom_sid *_sid) |
| 3212 | { |
| 3213 | int ret; |
| 3214 | char *filter; |
| 3215 | TALLOC_CTX *tmp_ctx; |
| 3216 | LDAPMessage *entry = NULL((void*)0); |
| 3217 | LDAPMessage *result = NULL((void*)0); |
| 3218 | char *sid_str = NULL((void*)0); |
| 3219 | struct dom_sid *sid = NULL((void*)0); |
| 3220 | int count; |
| 3221 | enum idmap_error_code err; |
| 3222 | struct unixid id; |
| 3223 | |
| 3224 | tmp_ctx = talloc_init("ipasam_get_sid_by_gid"); |
| 3225 | if (tmp_ctx == NULL((void*)0)) { |
| 3226 | return ENOMEM12; |
| 3227 | } |
| 3228 | |
| 3229 | filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s)(%s=%lu))", |
| 3230 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 3231 | LDAP_OBJ_POSIXGROUP"posixGroup", |
| 3232 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 3233 | LDAP_OBJ_GROUPMAP"ipaNTGroupAttrs", |
| 3234 | LDAP_ATTRIBUTE_GIDNUMBER"gidnumber", |
| 3235 | (unsigned long) gid); |
| 3236 | if (filter == NULL((void*)0)) { |
| 3237 | ret = ENOMEM12; |
| 3238 | goto done; |
| 3239 | } |
| 3240 | |
| 3241 | ret = smbldap_search(ipasam_state->ldap_state, |
| 3242 | ipasam_state->base_dn, |
| 3243 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002),filter, NULL((void*)0), 0, |
| 3244 | &result); |
| 3245 | if (ret != LDAP_SUCCESS0x00) { |
| 3246 | ret = ENOENT2; |
| 3247 | goto done; |
| 3248 | } |
| 3249 | |
| 3250 | count = ldap_count_entries(priv2ld(ipasam_state), result); |
| 3251 | if (count != 1) { |
| 3252 | ret = ENOENT2; |
| 3253 | goto done; |
| 3254 | } |
| 3255 | |
| 3256 | entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 3257 | if (entry == NULL((void*)0)) { |
| 3258 | ret = ENOENT2; |
| 3259 | goto done; |
| 3260 | } |
| 3261 | |
| 3262 | sid_str = get_single_attribute(tmp_ctx, |
| 3263 | priv2ld(ipasam_state), |
| 3264 | entry, LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 3265 | if (sid_str == NULL((void*)0)) { |
| 3266 | ret = ENOENT2; |
| 3267 | goto done; |
| 3268 | } |
| 3269 | |
| 3270 | err = sss_idmap_sid_to_smb_sid(ipasam_state->idmap_ctx, |
| 3271 | sid_str, &sid); |
| 3272 | if (err != IDMAP_SUCCESS) { |
| 3273 | ret = EFAULT14; |
| 3274 | goto done; |
| 3275 | } |
| 3276 | sid_copy(_sid, sid); |
| 3277 | |
| 3278 | ipasam_unixid_from_gid(&id, gid); |
| 3279 | |
| 3280 | idmap_cache_set_sid2unixid(sid, &id); |
| 3281 | |
| 3282 | ret = 0; |
| 3283 | |
| 3284 | done: |
| 3285 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "3285"); |
| 3286 | ldap_msgfree(result); |
| 3287 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "3287"); |
| 3288 | |
| 3289 | return ret; |
| 3290 | } |
| 3291 | |
| 3292 | static int ipasam_get_primary_group_sid(TALLOC_CTX *mem_ctx, |
| 3293 | struct ipasam_private *ipasam_state, |
| 3294 | LDAPMessage *entry, |
| 3295 | struct dom_sid **_group_sid) |
| 3296 | { |
| 3297 | int ret; |
| 3298 | uint32_t uid; |
| 3299 | uint32_t gid; |
| 3300 | struct dom_sid *group_sid; |
| 3301 | struct unixid id; |
| 3302 | |
| 3303 | TALLOC_CTX *tmp_ctx = talloc_init("ipasam_get_primary_group_sid"); |
| 3304 | if (tmp_ctx == NULL((void*)0)) { |
| 3305 | return ENOMEM12; |
| 3306 | } |
| 3307 | |
| 3308 | if (!get_uint32_t_from_ldap_msg(ipasam_state, entry, |
| 3309 | LDAP_ATTRIBUTE_UIDNUMBER"uidnumber", &uid)) { |
| 3310 | ret = ENOENT2; |
| 3311 | DEBUG(1, ("No uidnumber attribute found for this user!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3311", __FUNCTION__ )) && (dbgtext ("No uidnumber attribute found for this user!\n" )) ); |
| 3312 | goto done; |
| 3313 | } |
| 3314 | |
| 3315 | if (!get_uint32_t_from_ldap_msg(ipasam_state, entry, |
| 3316 | LDAP_ATTRIBUTE_GIDNUMBER"gidnumber", &gid)) { |
| 3317 | ret = ENOENT2; |
| 3318 | DEBUG(1, ("No gidnumber attribute found for this user!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3318", __FUNCTION__ )) && (dbgtext ("No gidnumber attribute found for this user!\n" )) ); |
| 3319 | goto done; |
| 3320 | } |
| 3321 | |
| 3322 | group_sid = talloc(tmp_ctx, struct dom_sid)(struct dom_sid *)talloc_named_const(tmp_ctx, sizeof(struct dom_sid ), "struct dom_sid"); |
| 3323 | if (group_sid == NULL((void*)0)) { |
| 3324 | ret = ENOMEM12; |
| 3325 | goto done; |
| 3326 | } |
| 3327 | |
| 3328 | if (uid == gid) { /* User private group, use default fallback group */ |
| 3329 | sid_copy(group_sid, |
| 3330 | &ipasam_state->fallback_primary_group); |
| 3331 | ret = 0; |
| 3332 | goto done; |
| 3333 | } else { |
| 3334 | ret = ipasam_get_sid_by_gid(ipasam_state, gid, group_sid); |
| 3335 | if (ret != 0) { |
| 3336 | goto done; |
| 3337 | } |
| 3338 | } |
| 3339 | |
| 3340 | ipasam_unixid_from_gid(&id, gid); |
| 3341 | |
| 3342 | idmap_cache_set_sid2unixid(group_sid, &id); |
| 3343 | |
| 3344 | ret = 0; |
| 3345 | done: |
| 3346 | |
| 3347 | if (ret == 0) { |
| 3348 | *_group_sid = talloc_steal(mem_ctx, group_sid)({ __typeof__(group_sid) __talloc_steal_ret = (__typeof__(group_sid ))_talloc_steal_loc((mem_ctx),(group_sid), "ipa_sam.c" ":" "3348" ); __talloc_steal_ret; }); |
| 3349 | } |
| 3350 | |
| 3351 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "3351"); |
| 3352 | |
| 3353 | return ret; |
| 3354 | } |
| 3355 | |
| 3356 | static bool_Bool init_sam_from_ldap(struct ipasam_private *ipasam_state, |
| 3357 | struct samu * sampass, |
| 3358 | LDAPMessage * entry) |
| 3359 | { |
| 3360 | char *username = NULL((void*)0); |
| 3361 | struct berval **usernames = NULL((void*)0); |
| 3362 | char *domain = NULL((void*)0); |
| 3363 | char *nt_username = NULL((void*)0); |
| 3364 | char *fullname = NULL((void*)0); |
| 3365 | char *homedir = NULL((void*)0); |
| 3366 | char *dir_drive = NULL((void*)0); |
| 3367 | char *logon_script = NULL((void*)0); |
| 3368 | char *profile_path = NULL((void*)0); |
| 3369 | char *temp = NULL((void*)0); |
| 3370 | bool_Bool ret = false0; |
| 3371 | bool_Bool retval = false0; |
| 3372 | bool_Bool machine_account = false0; |
| 3373 | int status; |
| 3374 | int len = 0; |
| 3375 | int idx = 0; |
| 3376 | size_t conv_size = 0; |
| 3377 | DATA_BLOB nthash; |
| 3378 | struct dom_sid *group_sid; |
| 3379 | |
| 3380 | TALLOC_CTX *tmp_ctx = talloc_init("init_sam_from_ldap"); |
| 3381 | if (!tmp_ctx) { |
| 3382 | return false0; |
| 3383 | } |
| 3384 | if (sampass == NULL((void*)0) || ipasam_state == NULL((void*)0) || entry == NULL((void*)0)) { |
| 3385 | DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3385", __FUNCTION__ )) && (dbgtext ("init_sam_from_ldap: NULL parameters found!\n" )) ); |
| 3386 | goto fn_exit; |
| 3387 | } |
| 3388 | |
| 3389 | if (priv2ld(ipasam_state) == NULL((void*)0)) { |
| 3390 | DEBUG(0, ("init_sam_from_ldap: ipasam_state->ldap_state->"(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3391", __FUNCTION__ )) && (dbgtext ("init_sam_from_ldap: ipasam_state->ldap_state->" "ldap_struct is NULL!\n")) ) |
| 3391 | "ldap_struct is NULL!\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3391", __FUNCTION__ )) && (dbgtext ("init_sam_from_ldap: ipasam_state->ldap_state->" "ldap_struct is NULL!\n")) ); |
| 3392 | goto fn_exit; |
| 3393 | } |
| 3394 | |
| 3395 | usernames = ldap_get_values_len(priv2ld(ipasam_state), entry, |
| 3396 | LDAP_ATTRIBUTE_UID"uid"); |
| 3397 | |
| 3398 | if (usernames == NULL((void*)0)) { |
| 3399 | DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3400", __FUNCTION__ )) && (dbgtext ("init_sam_from_ldap: No uid attribute found for " "this user!\n")) ) |
| 3400 | "this user!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3400", __FUNCTION__ )) && (dbgtext ("init_sam_from_ldap: No uid attribute found for " "this user!\n")) ); |
| 3401 | goto fn_exit; |
| 3402 | } |
| 3403 | |
| 3404 | len = ldap_count_values_len(usernames); |
| 3405 | if (len > 1) { |
| 3406 | /* Extract machine account as a user name if exists. |
| 3407 | * If not, extract the first returned value */ |
| 3408 | for (int i=0; i < len; i++) { |
| 3409 | if (usernames[i] != NULL((void*)0) && |
| 3410 | usernames[i]->bv_len > 0 && |
| 3411 | usernames[i]->bv_val[usernames[i]->bv_len-1] == '$') { |
| 3412 | idx = i; |
| 3413 | machine_account = true1; |
| 3414 | break; |
| 3415 | } |
| 3416 | } |
| 3417 | } |
| 3418 | |
| 3419 | /* convert_string_talloc() will eventually call smb_iconv() which will |
| 3420 | * implicitly allocate space for NULL-termination in an encoding we use, |
| 3421 | * thus we are OK with passing non-NULL-terminated source string. */ |
| 3422 | retval = convert_string_talloc(tmp_ctx, |
| 3423 | CH_UTF8, CH_UNIX, |
| 3424 | usernames[idx]->bv_val, |
| 3425 | usernames[idx]->bv_len, |
| 3426 | (void**)&username, |
| 3427 | &conv_size); |
| 3428 | |
| 3429 | if (!retval) { |
| 3430 | DEBUG(1, ("init_sam_from_ldap: error converting uid to UNIX encoding!\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3430", __FUNCTION__ )) && (dbgtext ("init_sam_from_ldap: error converting uid to UNIX encoding!\n" )) ); |
| 3431 | goto fn_exit; |
| 3432 | } |
| 3433 | |
| 3434 | DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "3434", __FUNCTION__ )) && (dbgtext ("init_sam_from_ldap: Entry found for user: %s\n" , username)) ); |
| 3435 | |
| 3436 | nt_username = talloc_strdup(tmp_ctx, username); |
| 3437 | if (!nt_username) { |
| 3438 | goto fn_exit; |
| 3439 | } |
| 3440 | |
| 3441 | domain = talloc_strdup(tmp_ctx, ipasam_state->domain_name); |
| 3442 | if (!domain) { |
| 3443 | goto fn_exit; |
| 3444 | } |
| 3445 | |
| 3446 | pdb_set_username(sampass, username, PDB_SET); |
| 3447 | |
| 3448 | pdb_set_domain(sampass, domain, PDB_DEFAULT); |
| 3449 | pdb_set_nt_username(sampass, nt_username, PDB_SET); |
| 3450 | |
| 3451 | if ((temp = smbldap_talloc_single_attribute( |
| 3452 | priv2ld(ipasam_state), |
| 3453 | entry, LDAP_ATTRIBUTE_SECURITY_IDENTIFIER"ipaNTSecurityIdentifier", |
| 3454 | tmp_ctx)) != NULL((void*)0)) { |
| 3455 | pdb_set_user_sid_from_string(sampass, temp, PDB_SET); |
| 3456 | |
| 3457 | status = ipasam_get_primary_group_sid(tmp_ctx, ipasam_state, |
| 3458 | entry, &group_sid); |
| 3459 | if (status != 0) { |
| 3460 | goto fn_exit; |
| 3461 | } |
| 3462 | } else { |
| 3463 | goto fn_exit; |
| 3464 | } |
| 3465 | |
| 3466 | fullname = smbldap_talloc_single_attribute( |
| 3467 | priv2ld(ipasam_state), |
| 3468 | entry, |
| 3469 | LDAP_ATTRIBUTE_CN"cn", |
| 3470 | tmp_ctx); |
| 3471 | if (fullname) { |
| 3472 | pdb_set_fullname(sampass, fullname, PDB_SET); |
| 3473 | } |
| 3474 | |
| 3475 | dir_drive = smbldap_talloc_single_attribute( |
| 3476 | priv2ld(ipasam_state), |
| 3477 | entry, LDAP_ATTRIBUTE_HOME_DRIVE"ipaNTHomeDirectoryDrive", tmp_ctx); |
| 3478 | if (dir_drive) { |
| 3479 | pdb_set_dir_drive(sampass, dir_drive, PDB_SET); |
| 3480 | } |
| 3481 | |
| 3482 | homedir = smbldap_talloc_single_attribute( |
| 3483 | priv2ld(ipasam_state), |
| 3484 | entry, LDAP_ATTRIBUTE_HOME_PATH"ipaNTHomeDirectory", tmp_ctx); |
| 3485 | if (homedir) { |
| 3486 | pdb_set_homedir(sampass, homedir, PDB_SET); |
| 3487 | } |
| 3488 | |
| 3489 | logon_script = smbldap_talloc_single_attribute( |
| 3490 | priv2ld(ipasam_state), |
| 3491 | entry, LDAP_ATTRIBUTE_LOGON_SCRIPT"ipaNTLogonScript", tmp_ctx); |
| 3492 | if (logon_script) { |
| 3493 | pdb_set_logon_script(sampass, logon_script, PDB_SET); |
| 3494 | } |
| 3495 | |
| 3496 | profile_path = smbldap_talloc_single_attribute( |
| 3497 | priv2ld(ipasam_state), |
| 3498 | entry, LDAP_ATTRIBUTE_PROFILE_PATH"ipaNTProfilePath", tmp_ctx); |
| 3499 | if (profile_path) { |
| 3500 | pdb_set_profile_path(sampass, profile_path, PDB_SET); |
| 3501 | } |
| 3502 | |
| 3503 | |
| 3504 | /* Force machine accounts to be workstation trust type */ |
| 3505 | pdb_set_acct_ctrl(sampass, machine_account ? ACB_WSTRUST( 0x00000080 ) : ACB_NORMAL( 0x00000010 ), |
| 3506 | PDB_SET); |
| 3507 | |
| 3508 | retval = smbldap_talloc_single_blob(tmp_ctx, |
| 3509 | priv2ld(ipasam_state), |
| 3510 | entry, LDAP_ATTRIBUTE_NTHASH"ipaNTHash", |
| 3511 | &nthash); |
| 3512 | if (!retval) { |
| 3513 | /* NT Hash is not in place. Attempt to retrieve it from |
| 3514 | * the RC4-HMAC key if that exists in Kerberos credentials. |
| 3515 | * IPA 389-ds plugin allows to ask for it by setting |
| 3516 | * ipaNTHash to MagicRegen value. |
| 3517 | * */ |
| 3518 | temp = smbldap_talloc_dn(tmp_ctx, priv2ld(ipasam_state), entry); |
| 3519 | if (temp) { |
| 3520 | retval = ipasam_nthash_regen(ipasam_state, |
| 3521 | tmp_ctx, temp); |
| 3522 | if (retval) { |
| 3523 | retval = ipasam_nthash_retrieve(ipasam_state, |
| 3524 | tmp_ctx, temp, &nthash); |
| 3525 | } |
| 3526 | } |
| 3527 | } |
| 3528 | |
| 3529 | if (!retval) { |
| 3530 | DEBUG(5, ("Failed to read NT hash form LDAP response.\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3530", __FUNCTION__ )) && (dbgtext ("Failed to read NT hash form LDAP response.\n" )) ); |
| 3531 | } |
| 3532 | |
| 3533 | if (nthash.length != NT_HASH_LEN16 && nthash.length != 0) { |
| 3534 | DEBUG(5, ("NT hash from LDAP has the wrong size. Perhaps password was not re-set?\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3534", __FUNCTION__ )) && (dbgtext ("NT hash from LDAP has the wrong size. Perhaps password was not re-set?\n" )) ); |
| 3535 | } else { |
| 3536 | if (!pdb_set_nt_passwd(sampass, nthash.data, PDB_SET)) { |
| 3537 | DEBUG(5, ("Failed to set NT hash.\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3537", __FUNCTION__ )) && (dbgtext ("Failed to set NT hash.\n")) ); |
| 3538 | } |
| 3539 | } |
| 3540 | /* FIXME: */ |
| 3541 | if (!pdb_set_pass_last_set_time(sampass, (time_t) 1, PDB_SET)) { |
| 3542 | DEBUG(5, ("Failed to set last time set.\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3542", __FUNCTION__ )) && (dbgtext ("Failed to set last time set.\n")) ); |
| 3543 | } |
| 3544 | |
| 3545 | ret = true1; |
| 3546 | |
| 3547 | fn_exit: |
| 3548 | |
| 3549 | if (usernames != NULL((void*)0)) { |
| 3550 | ldap_value_free_len(usernames); |
| 3551 | } |
| 3552 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "3552"); |
| 3553 | return ret; |
| 3554 | } |
| 3555 | |
| 3556 | static NTSTATUS getsam_interdom_trust_account(struct pdb_methods *methods, |
| 3557 | struct samu *user, |
| 3558 | const char *sname, int lastidx) |
| 3559 | { |
| 3560 | char *dom_name; |
| 3561 | struct ipasam_private *ipasam_state = |
| 3562 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "3562"); |
| 3563 | TALLOC_CTX *tmp_ctx; |
| 3564 | struct pdb_trusted_domain *td; |
| 3565 | NTSTATUS status; |
| 3566 | LDAPMessage *entry = NULL((void*)0); |
| 3567 | |
| 3568 | /* The caller must check that (sname[lastidx] == '.') || (sname[lastidx] == '$')) |
| 3569 | * before calling this function. |
| 3570 | */ |
| 3571 | |
| 3572 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "3572"); |
| 3573 | if (tmp_ctx == NULL((void*)0)) { |
| 3574 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3575 | } |
| 3576 | |
| 3577 | dom_name = talloc_strdup(tmp_ctx, sname); |
| 3578 | if (dom_name == NULL((void*)0)) { |
| 3579 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3580 | goto done; |
| 3581 | } |
| 3582 | dom_name[lastidx] = '\0'; |
| 3583 | |
| 3584 | if (!get_trusted_domain_by_name_int(ipasam_state, tmp_ctx, dom_name, |
| 3585 | &entry)) { |
| 3586 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 3587 | goto done; |
| 3588 | } |
| 3589 | if (entry == NULL((void*)0)) { |
| 3590 | DEBUG(5, ("getsam_interdom_trust_account: no such trusted " \(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3591", __FUNCTION__ )) && (dbgtext ("getsam_interdom_trust_account: no such trusted " "domain: %s\n", dom_name)) ) |
| 3591 | "domain: %s\n", dom_name))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3591", __FUNCTION__ )) && (dbgtext ("getsam_interdom_trust_account: no such trusted " "domain: %s\n", dom_name)) ); |
| 3592 | status = NT_STATUS_NO_SUCH_DOMAIN((NTSTATUS) { 0xc00000df }); |
| 3593 | goto done; |
| 3594 | } |
| 3595 | |
| 3596 | if (!fill_pdb_trusted_domain(tmp_ctx, ipasam_state, entry, &td)) { |
| 3597 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 3598 | goto done; |
| 3599 | } |
| 3600 | |
| 3601 | if (!init_sam_from_td(user, td, entry, ipasam_state)) { |
| 3602 | DEBUG(5, ("init_sam_from_td failed.\n"))(void)( ((5) <= 1000) && (debuglevel_get_class(0) >= (5)) && (dbghdrclass( 5, 0, "ipa_sam.c" ":" "3602", __FUNCTION__ )) && (dbgtext ("init_sam_from_td failed.\n")) ); |
| 3603 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3604 | goto done; |
| 3605 | } |
| 3606 | |
| 3607 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 3608 | |
| 3609 | done: |
| 3610 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "3610"); |
| 3611 | return status; |
| 3612 | } |
| 3613 | |
| 3614 | /* |
| 3615 | * lookup of an account by SID |
| 3616 | * |
| 3617 | * Samba may ask for an account based on a SID value. Implement a callback to |
| 3618 | * return a result of such lookup since we should have SID for every domain |
| 3619 | * account that is supposed to be usable through SMB protocol. |
| 3620 | */ |
| 3621 | static NTSTATUS ipasam_getsampwsid(struct pdb_methods *methods, |
| 3622 | struct samu *user, |
| 3623 | const struct dom_sid *sid) |
| 3624 | { |
| 3625 | struct ipasam_private *ipasam_state = |
| 3626 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "3626"); |
| 3627 | TALLOC_CTX *tmp_ctx; |
| 3628 | NTSTATUS status; |
| 3629 | char *filter = NULL((void*)0); |
| 3630 | char *sid_str = NULL((void*)0); |
| 3631 | LDAPMessage *result = NULL((void*)0); |
| 3632 | LDAPMessage *entry = NULL((void*)0); |
| 3633 | int ret; |
| 3634 | int count; |
| 3635 | |
| 3636 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "3636"); |
| 3637 | if (tmp_ctx == NULL((void*)0)) { |
| 3638 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3639 | } |
| 3640 | |
| 3641 | sid_str = sid_talloc_string(ipasam_state->idmap_ctx, tmp_ctx, sid); |
| 3642 | if (sid_str == NULL((void*)0)) { |
| 3643 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3644 | goto done; |
| 3645 | } |
| 3646 | |
| 3647 | filter = talloc_asprintf(tmp_ctx, "(&(|(%s=%s)(%s=%s))(%s=%s))", |
| 3648 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 3649 | LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs", |
| 3650 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 3651 | LDAP_OBJ_ID_OBJECT"ipaIDobject", |
| 3652 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", sid_str); |
| 3653 | if (filter == NULL((void*)0)) { |
| 3654 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3655 | goto done; |
| 3656 | } |
| 3657 | |
| 3658 | ret = smbldap_search(ipasam_state->ldap_state, |
| 3659 | ipasam_state->base_dn, |
| 3660 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), filter, NULL((void*)0), 0, |
| 3661 | &result); |
| 3662 | if (ret != LDAP_SUCCESS0x00) { |
| 3663 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3664 | goto done; |
| 3665 | } |
| 3666 | |
| 3667 | count = ldap_count_entries(priv2ld(ipasam_state), result); |
| 3668 | if (count != 1) { |
| 3669 | DEBUG(3, ("Expected single entry returned for a SID lookup. "(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "3670", __FUNCTION__ )) && (dbgtext ("Expected single entry returned for a SID lookup. " "Got %d. Refuse lookup by SID %s", count, sid_str)) ) |
| 3670 | "Got %d. Refuse lookup by SID %s", count, sid_str))(void)( ((3) <= 1000) && (debuglevel_get_class(0) >= (3)) && (dbghdrclass( 3, 0, "ipa_sam.c" ":" "3670", __FUNCTION__ )) && (dbgtext ("Expected single entry returned for a SID lookup. " "Got %d. Refuse lookup by SID %s", count, sid_str)) ); |
| 3671 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3672 | goto done; |
| 3673 | } |
| 3674 | |
| 3675 | entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 3676 | if (entry == NULL((void*)0)) { |
| 3677 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3678 | goto done; |
| 3679 | } |
| 3680 | |
| 3681 | if (!init_sam_from_ldap(ipasam_state, user, entry)) { |
| 3682 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3683 | goto done; |
| 3684 | } |
| 3685 | |
| 3686 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 3687 | |
| 3688 | done: |
| 3689 | if (result != NULL((void*)0)) { |
| 3690 | ldap_msgfree(result); |
| 3691 | } |
| 3692 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "3692"); |
| 3693 | return status; |
| 3694 | } |
| 3695 | |
| 3696 | |
| 3697 | static NTSTATUS ipasam_getsampwnam(struct pdb_methods *methods, |
| 3698 | struct samu *user, |
| 3699 | const char *sname) |
| 3700 | { |
| 3701 | struct ipasam_private *ipasam_state = |
| 3702 | talloc_get_type_abort(methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(methods->private_data , "struct ipasam_private", "ipa_sam.c" ":" "3702"); |
| 3703 | int lastidx; |
| 3704 | TALLOC_CTX *tmp_ctx; |
| 3705 | NTSTATUS status; |
| 3706 | char *filter; |
| 3707 | char *escaped_user; |
| 3708 | LDAPMessage *result = NULL((void*)0); |
| 3709 | LDAPMessage *entry = NULL((void*)0); |
| 3710 | int ret; |
| 3711 | int count; |
| 3712 | |
| 3713 | lastidx = strlen(sname); |
| 3714 | if (lastidx > 0) { |
| 3715 | lastidx--; |
| 3716 | } else { |
| 3717 | /* strlen() must return >= 0 so it means we've got an empty name */ |
| 3718 | return NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3719 | } |
| 3720 | if ((sname[lastidx] == '.') || (sname[lastidx] == '$')) { |
| 3721 | status = getsam_interdom_trust_account(methods, user, sname, lastidx); |
| 3722 | /* If last character was '$', we should ignore failure and continue |
| 3723 | * as this could still be a machine account */ |
| 3724 | if ((sname[lastidx] == '.') || NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 3725 | return status; |
| 3726 | } |
| 3727 | } |
| 3728 | |
| 3729 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "3729"); |
| 3730 | if (tmp_ctx == NULL((void*)0)) { |
| 3731 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3732 | } |
| 3733 | |
| 3734 | escaped_user = escape_ldap_string(tmp_ctx, sname); |
| 3735 | if (escaped_user == NULL((void*)0)) { |
| 3736 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3737 | goto done; |
| 3738 | } |
| 3739 | |
| 3740 | filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))", |
| 3741 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 3742 | LDAP_OBJ_SAMBASAMACCOUNT"ipaNTUserAttrs", |
| 3743 | LDAP_ATTRIBUTE_UID"uid", escaped_user); |
| 3744 | if (filter == NULL((void*)0)) { |
| 3745 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 3746 | goto done; |
| 3747 | } |
| 3748 | |
| 3749 | ret = smbldap_search(ipasam_state->ldap_state, |
| 3750 | ipasam_state->base_dn, |
| 3751 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002),filter, NULL((void*)0), 0, |
| 3752 | &result); |
| 3753 | if (ret != LDAP_SUCCESS0x00) { |
| 3754 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3755 | goto done; |
| 3756 | } |
| 3757 | |
| 3758 | count = ldap_count_entries(priv2ld(ipasam_state), result); |
| 3759 | if (count != 1) { |
| 3760 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3761 | goto done; |
| 3762 | } |
| 3763 | |
| 3764 | entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 3765 | if (entry == NULL((void*)0)) { |
| 3766 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3767 | goto done; |
| 3768 | } |
| 3769 | |
| 3770 | if (!init_sam_from_ldap(ipasam_state, user, entry)) { |
| 3771 | status = NT_STATUS_NO_SUCH_USER((NTSTATUS) { 0xc0000064 }); |
| 3772 | goto done; |
| 3773 | } |
| 3774 | |
| 3775 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 3776 | |
| 3777 | done: |
| 3778 | ldap_msgfree(result); |
| 3779 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "3779"); |
| 3780 | return status; |
| 3781 | } |
| 3782 | |
| 3783 | static bool_Bool ipasam_get_trusteddom_pw(struct pdb_methods *methods, |
| 3784 | const char *domain, |
| 3785 | char** pwd, |
| 3786 | struct dom_sid *sid, |
| 3787 | time_t *pass_last_set_time) |
| 3788 | { |
| 3789 | NTSTATUS status; |
| 3790 | TALLOC_CTX *tmp_ctx; |
| 3791 | struct pdb_trusted_domain *td; |
| 3792 | bool_Bool ret = false0; |
| 3793 | char *trustpw; |
| 3794 | NTTIME last_update; |
| 3795 | |
| 3796 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "3796"); |
| 3797 | if (tmp_ctx == NULL((void*)0)) { |
| 3798 | return false0; |
| 3799 | } |
| 3800 | |
| 3801 | status = ipasam_get_trusted_domain(methods, tmp_ctx, domain, &td); |
| 3802 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 3803 | ret = false0; |
| 3804 | goto done; |
| 3805 | } |
| 3806 | |
| 3807 | status = get_trust_pwd(tmp_ctx, &td->trust_auth_incoming, |
| 3808 | &trustpw, &last_update); |
| 3809 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 3810 | ret = false0; |
| 3811 | goto done; |
| 3812 | } |
| 3813 | |
| 3814 | /* trusteddom_pw routines do not use talloc yet... */ |
| 3815 | if (pwd != NULL((void*)0)) { |
| 3816 | *pwd = strdup(trustpw); |
| 3817 | memset(trustpw, 0, strlen(trustpw)); |
| 3818 | talloc_free(trustpw)_talloc_free(trustpw, "ipa_sam.c" ":" "3818"); |
| 3819 | if (*pwd == NULL((void*)0)) { |
| 3820 | ret =false0; |
| 3821 | goto done; |
| 3822 | } |
| 3823 | } |
| 3824 | |
| 3825 | if (pass_last_set_time != NULL((void*)0)) { |
| 3826 | *pass_last_set_time = nt_time_to_unix(last_update); |
| 3827 | } |
| 3828 | |
| 3829 | if (sid != NULL((void*)0)) { |
| 3830 | sid_copy(sid, &td->security_identifier); |
| 3831 | } |
| 3832 | |
| 3833 | ret = true1; |
| 3834 | done: |
| 3835 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "3835"); |
| 3836 | return ret; |
| 3837 | } |
| 3838 | |
| 3839 | static bool_Bool ipasam_set_trusteddom_pw(struct pdb_methods *methods, |
| 3840 | const char* domain, |
| 3841 | const char* pwd, |
| 3842 | const struct dom_sid *sid) |
| 3843 | { |
| 3844 | return false0; |
| 3845 | } |
| 3846 | |
| 3847 | static bool_Bool ipasam_del_trusteddom_pw(struct pdb_methods *methods, |
| 3848 | const char *domain) |
| 3849 | { |
| 3850 | return false0; |
| 3851 | } |
| 3852 | |
| 3853 | static struct pdb_domain_info *pdb_ipasam_get_domain_info(struct pdb_methods *pdb_methods, |
| 3854 | TALLOC_CTX *mem_ctx) |
| 3855 | { |
| 3856 | struct pdb_domain_info *info; |
| 3857 | struct ipasam_private *ipasam_state = |
| 3858 | talloc_get_type_abort(pdb_methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(pdb_methods-> private_data, "struct ipasam_private", "ipa_sam.c" ":" "3858" ); |
| 3859 | char sid_buf[24]; |
| 3860 | DATA_BLOB sid_blob; |
| 3861 | NTSTATUS status; |
| 3862 | |
| 3863 | info = talloc(mem_ctx, struct pdb_domain_info)(struct pdb_domain_info *)talloc_named_const(mem_ctx, sizeof( struct pdb_domain_info), "struct pdb_domain_info"); |
| 3864 | if (info == NULL((void*)0)) { |
| 3865 | DEBUG(1, ("talloc failed\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3865", __FUNCTION__ )) && (dbgtext ("talloc failed\n")) ); |
| 3866 | return NULL((void*)0); |
| 3867 | } |
| 3868 | |
| 3869 | info->name = talloc_strdup(info, ipasam_state->flat_name); |
| 3870 | if (info->name == NULL((void*)0)) { |
| 3871 | DEBUG(1, ("talloc_strdup domain_name failed\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3871", __FUNCTION__ )) && (dbgtext ("talloc_strdup domain_name failed\n" )) ); |
| 3872 | goto fail; |
| 3873 | } |
| 3874 | |
| 3875 | status = ipasam_get_domain_name(ipasam_state, info, &info->dns_domain); |
| 3876 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0)) || (info->dns_domain == NULL((void*)0))) { |
| 3877 | goto fail; |
| 3878 | } |
| 3879 | info->dns_forest = talloc_strdup(info, info->dns_domain); |
| 3880 | |
| 3881 | /* we expect a domain SID to have 4 sub IDs */ |
| 3882 | if (ipasam_state->domain_sid.num_auths != 4) { |
| 3883 | goto fail; |
| 3884 | } |
| 3885 | |
| 3886 | sid_copy(&info->sid, &ipasam_state->domain_sid); |
| 3887 | |
| 3888 | if (!sid_linearize(sid_buf, sizeof(sid_buf), &info->sid)) { |
| 3889 | goto fail; |
| 3890 | } |
| 3891 | |
| 3892 | /* the first 8 bytes of the linearized SID are not random, |
| 3893 | * so we skip them */ |
| 3894 | sid_blob.data = (uint8_t *) sid_buf + 8 ; |
| 3895 | sid_blob.length = 16; |
| 3896 | |
| 3897 | status = GUID_from_ndr_blob(&sid_blob, &info->guid); |
| 3898 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 3899 | goto fail; |
| 3900 | } |
| 3901 | |
| 3902 | return info; |
| 3903 | |
| 3904 | fail: |
| 3905 | TALLOC_FREE(info)do { if (info != ((void*)0)) { _talloc_free(info, "ipa_sam.c" ":" "3905"); info=((void*)0); } } while(0); |
| 3906 | return NULL((void*)0); |
| 3907 | } |
| 3908 | |
| 3909 | static void ipasam_free_private_data(void **vp) |
| 3910 | { |
| 3911 | struct ipasam_private **ipasam_state = (struct ipasam_private **)vp; |
| 3912 | |
| 3913 | smbldap_free_struct(&(*ipasam_state)->ldap_state); |
| 3914 | |
| 3915 | if ((*ipasam_state)->result != NULL((void*)0)) { |
| 3916 | ldap_msgfree((*ipasam_state)->result); |
| 3917 | (*ipasam_state)->result = NULL((void*)0); |
| 3918 | } |
| 3919 | if ((*ipasam_state)->domain_dn != NULL((void*)0)) { |
| 3920 | free((*ipasam_state)->domain_dn); |
| 3921 | (*ipasam_state)->domain_dn = NULL((void*)0); |
| 3922 | } |
| 3923 | |
| 3924 | *ipasam_state = NULL((void*)0); |
| 3925 | |
| 3926 | /* No need to free any further, as it is talloc()ed */ |
| 3927 | } |
| 3928 | |
| 3929 | static struct dom_sid *get_fallback_group_sid(TALLOC_CTX *mem_ctx, |
| 3930 | struct smbldap_state *ldap_state, |
| 3931 | struct sss_idmap_ctx *idmap_ctx, |
| 3932 | LDAPMessage *dom_entry, |
| 3933 | char **fallback_group_gid_str) |
| 3934 | { |
| 3935 | char *dn; |
| 3936 | char *sid; |
| 3937 | char *gidnumber; |
| 3938 | int ret; |
| 3939 | const char *filter = "objectClass=*"; |
| 3940 | const char *attr_list[] = { |
| 3941 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 3942 | LDAP_ATTRIBUTE_GIDNUMBER"gidnumber", |
| 3943 | NULL((void*)0)}; |
| 3944 | LDAPMessage *result; |
| 3945 | LDAPMessage *entry; |
| 3946 | LDAP *ld = NULL((void*)0); |
| 3947 | enum idmap_error_code err; |
| 3948 | struct dom_sid *fallback_group_sid; |
| 3949 | |
| 3950 | ld = _smbldap_get_ldap(ldap_state); |
| 3951 | dn = get_single_attribute(mem_ctx, ld, |
| 3952 | dom_entry, |
| 3953 | LDAP_ATTRIBUTE_FALLBACK_PRIMARY_GROUP"ipaNTFallbackPrimaryGroup"); |
| 3954 | if (dn == NULL((void*)0)) { |
| 3955 | DEBUG(0, ("Missing mandatory attribute %s.\n",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3956", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "ipaNTFallbackPrimaryGroup")) ) |
| 3956 | LDAP_ATTRIBUTE_FALLBACK_PRIMARY_GROUP))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3956", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "ipaNTFallbackPrimaryGroup")) ); |
| 3957 | return NULL((void*)0); |
| 3958 | } |
| 3959 | |
| 3960 | ret = smbldap_search(ldap_state, dn, LDAP_SCOPE_BASE((ber_int_t) 0x0000), filter, attr_list, |
| 3961 | 0, &result); |
| 3962 | talloc_free(dn)_talloc_free(dn, "ipa_sam.c" ":" "3962"); |
| 3963 | if (ret != LDAP_SUCCESS0x00) { |
| 3964 | DEBUG(2,("Failed to read faillback group [%s].", dn))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "3964", __FUNCTION__ )) && (dbgtext ("Failed to read faillback group [%s]." , dn)) ); |
| 3965 | return NULL((void*)0); |
| 3966 | } |
| 3967 | |
| 3968 | ld = _smbldap_get_ldap(ldap_state); |
| 3969 | entry = ldap_first_entry(ld, result); |
| 3970 | if (entry == NULL((void*)0)) { |
| 3971 | DEBUG(0, ("Could not get fallback group entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3971", __FUNCTION__ )) && (dbgtext ("Could not get fallback group entry\n" )) ); |
| 3972 | ldap_msgfree(result); |
| 3973 | return NULL((void*)0); |
| 3974 | } |
| 3975 | |
| 3976 | sid = get_single_attribute(mem_ctx, ld, |
| 3977 | entry, LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 3978 | if (sid == NULL((void*)0)) { |
| 3979 | DEBUG(0, ("Missing mandatory attribute %s.\n",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3980", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "ipaNTSecurityIdentifier")) ) |
| 3980 | LDAP_ATTRIBUTE_SID))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3980", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "ipaNTSecurityIdentifier")) ); |
| 3981 | ldap_msgfree(result); |
| 3982 | return NULL((void*)0); |
| 3983 | } |
| 3984 | |
| 3985 | err = sss_idmap_sid_to_smb_sid(idmap_ctx, sid, &fallback_group_sid); |
| 3986 | if (err != IDMAP_SUCCESS) { |
| 3987 | DEBUG(1, ("SID [%s] could not be converted\n", sid))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "3987", __FUNCTION__ )) && (dbgtext ("SID [%s] could not be converted\n", sid)) ); |
| 3988 | ldap_msgfree(result); |
| 3989 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "3989"); |
| 3990 | return NULL((void*)0); |
| 3991 | } |
| 3992 | talloc_free(sid)_talloc_free(sid, "ipa_sam.c" ":" "3992"); |
| 3993 | |
| 3994 | gidnumber = get_single_attribute(mem_ctx, ld, |
| 3995 | entry, LDAP_ATTRIBUTE_GIDNUMBER"gidnumber"); |
| 3996 | if (gidnumber == NULL((void*)0)) { |
| 3997 | DEBUG(0, ("Missing mandatory attribute %s.\n",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3998", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "gidnumber")) ) |
| 3998 | LDAP_ATTRIBUTE_GIDNUMBER))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "3998", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "gidnumber")) ); |
| 3999 | ldap_msgfree(result); |
| 4000 | return NULL((void*)0); |
| 4001 | } |
| 4002 | |
| 4003 | *fallback_group_gid_str = gidnumber; |
| 4004 | |
| 4005 | ldap_msgfree(result); |
| 4006 | |
| 4007 | return fallback_group_sid; |
| 4008 | } |
| 4009 | |
| 4010 | static NTSTATUS ipasam_search_domain_info(struct smbldap_state *ldap_state, |
| 4011 | LDAPMessage ** result) |
| 4012 | { |
| 4013 | const char *filter = "objectClass=ipaNTDomainAttrs"; |
| 4014 | const char *attr_list[] = { |
| 4015 | LDAP_ATTRIBUTE_FLAT_NAME"ipaNTFlatName", |
| 4016 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier", |
| 4017 | LDAP_ATTRIBUTE_FALLBACK_PRIMARY_GROUP"ipaNTFallbackPrimaryGroup", |
| 4018 | LDAP_ATTRIBUTE_OBJECTCLASS"objectClass", |
| 4019 | NULL((void*)0)}; |
| 4020 | int count; |
| 4021 | int ret; |
| 4022 | |
| 4023 | ret = smbldap_search_suffix(ldap_state, filter, attr_list , result); |
| 4024 | |
| 4025 | if (ret != LDAP_SUCCESS0x00) { |
| 4026 | DEBUG(2,("ipasam_search_domain_info: "(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "4028", __FUNCTION__ )) && (dbgtext ("ipasam_search_domain_info: " "smbldap_search_suffix failed: %s\n" , ldap_err2string (ret))) ) |
| 4027 | "smbldap_search_suffix failed: %s\n",(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "4028", __FUNCTION__ )) && (dbgtext ("ipasam_search_domain_info: " "smbldap_search_suffix failed: %s\n" , ldap_err2string (ret))) ) |
| 4028 | ldap_err2string (ret)))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "4028", __FUNCTION__ )) && (dbgtext ("ipasam_search_domain_info: " "smbldap_search_suffix failed: %s\n" , ldap_err2string (ret))) ); |
| 4029 | DEBUG(2,("ipasam_search_domain_info: Query was: %s\n", filter))(void)( ((2) <= 1000) && (debuglevel_get_class(0) >= (2)) && (dbghdrclass( 2, 0, "ipa_sam.c" ":" "4029", __FUNCTION__ )) && (dbgtext ("ipasam_search_domain_info: Query was: %s\n" , filter)) ); |
| 4030 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4031 | } |
| 4032 | |
| 4033 | count = ldap_count_entries(_smbldap_get_ldap(ldap_state), *result); |
| 4034 | |
| 4035 | if (count == 1) { |
| 4036 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4037 | } |
| 4038 | |
| 4039 | DEBUG(0, ("iapsam_search_domain_info: Got [%d] domain info entries, "(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4040", __FUNCTION__ )) && (dbgtext ("iapsam_search_domain_info: Got [%d] domain info entries, " "but expected only 1.\n", count)) ) |
| 4040 | "but expected only 1.\n", count))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4040", __FUNCTION__ )) && (dbgtext ("iapsam_search_domain_info: Got [%d] domain info entries, " "but expected only 1.\n", count)) ); |
| 4041 | |
| 4042 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4043 | } |
| 4044 | |
| 4045 | static NTSTATUS ipasam_get_base_dn(struct smbldap_state *ldap_state, |
| 4046 | TALLOC_CTX *mem_ctx, char **base_dn) |
| 4047 | { |
| 4048 | int ret; |
| 4049 | LDAPMessage *result; |
| 4050 | LDAPMessage *entry = NULL((void*)0); |
| 4051 | LDAP *ld = NULL((void*)0); |
| 4052 | int count; |
| 4053 | char *nc; |
| 4054 | const char *attr_list[] = { |
| 4055 | "namingContexts", |
| 4056 | "defaultNamingContext", |
| 4057 | NULL((void*)0) |
| 4058 | }; |
| 4059 | |
| 4060 | ret = smbldap_search(ldap_state, "", LDAP_SCOPE_BASE((ber_int_t) 0x0000), |
| 4061 | "(objectclass=*)", attr_list, 0, &result); |
| 4062 | if (ret != LDAP_SUCCESS0x00) { |
| 4063 | DEBUG(1, ("Failed to get base DN from RootDSE: %s\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4064", __FUNCTION__ )) && (dbgtext ("Failed to get base DN from RootDSE: %s\n" , ldap_err2string (ret))) ) |
| 4064 | ldap_err2string (ret)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4064", __FUNCTION__ )) && (dbgtext ("Failed to get base DN from RootDSE: %s\n" , ldap_err2string (ret))) ); |
| 4065 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4066 | } |
| 4067 | |
| 4068 | ld = _smbldap_get_ldap(ldap_state); |
| 4069 | count = ldap_count_entries(ld, result); |
| 4070 | |
| 4071 | if (count != 1) { |
| 4072 | DEBUG(1, ("Unexpected number of results [%d] for base DN "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4073", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for base DN " "search.\n", count)) ) |
| 4073 | "search.\n", count))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4073", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for base DN " "search.\n", count)) ); |
| 4074 | ldap_msgfree(result); |
| 4075 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4076 | } |
| 4077 | |
| 4078 | entry = ldap_first_entry(ld, result); |
| 4079 | if (entry == NULL((void*)0)) { |
| 4080 | DEBUG(0, ("Could not get RootDSE entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4080", __FUNCTION__ )) && (dbgtext ("Could not get RootDSE entry\n")) ); |
| 4081 | ldap_msgfree(result); |
| 4082 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4083 | } |
| 4084 | |
| 4085 | nc = get_single_attribute(mem_ctx, ld, entry, |
| 4086 | "defaultNamingContext"); |
| 4087 | if (nc != NULL((void*)0)) { |
| 4088 | *base_dn = nc; |
| 4089 | ldap_msgfree(result); |
| 4090 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4091 | } |
| 4092 | |
| 4093 | nc = get_single_attribute(mem_ctx, ld, entry, |
| 4094 | "namingContexts"); |
| 4095 | if (nc != NULL((void*)0)) { |
| 4096 | *base_dn = nc; |
| 4097 | ldap_msgfree(result); |
| 4098 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4099 | } |
| 4100 | |
| 4101 | ldap_msgfree(result); |
| 4102 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4103 | } |
| 4104 | |
| 4105 | static NTSTATUS ipasam_get_domain_name(struct ipasam_private *ipasam_state, |
| 4106 | TALLOC_CTX *mem_ctx, |
| 4107 | char **domain_name) |
| 4108 | { |
| 4109 | int ret; |
| 4110 | LDAPMessage *result; |
| 4111 | LDAPMessage *entry = NULL((void*)0); |
| 4112 | LDAP *ld = NULL((void*)0); |
| 4113 | int count; |
| 4114 | char *cn; |
| 4115 | struct smbldap_state *ldap_state = ipasam_state->ldap_state; |
| 4116 | const char *attr_list[] = { |
| 4117 | LDAP_ATTRIBUTE_ASSOCIATED_DOMAIN"associatedDomain", |
| 4118 | NULL((void*)0) |
| 4119 | }; |
| 4120 | |
| 4121 | ret = smbldap_search(ldap_state, |
| 4122 | ipasam_state->base_dn, |
| 4123 | LDAP_SCOPE_BASE((ber_int_t) 0x0000), |
| 4124 | "objectclass=" LDAP_OBJ_DOMAINRELATED"domainRelatedObject", attr_list, 0, |
| 4125 | &result); |
| 4126 | if (ret != LDAP_SUCCESS0x00) { |
| 4127 | DEBUG(1, ("Failed to get domain name: %s\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4128", __FUNCTION__ )) && (dbgtext ("Failed to get domain name: %s\n", ldap_err2string (ret))) ) |
| 4128 | ldap_err2string (ret)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4128", __FUNCTION__ )) && (dbgtext ("Failed to get domain name: %s\n", ldap_err2string (ret))) ); |
| 4129 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4130 | } |
| 4131 | |
| 4132 | ld = _smbldap_get_ldap(ldap_state); |
| 4133 | count = ldap_count_entries(ld, result); |
| 4134 | |
| 4135 | if (count != 1) { |
| 4136 | DEBUG(1, ("Unexpected number of results [%d] for domain name "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4137", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for domain name " "search.\n", count)) ) |
| 4137 | "search.\n", count))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4137", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for domain name " "search.\n", count)) ); |
| 4138 | ldap_msgfree(result); |
| 4139 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4140 | } |
| 4141 | |
| 4142 | entry = ldap_first_entry(ld, result); |
| 4143 | if (entry == NULL((void*)0)) { |
| 4144 | DEBUG(0, ("Could not get domainRelatedObject entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4144", __FUNCTION__ )) && (dbgtext ("Could not get domainRelatedObject entry\n" )) ); |
| 4145 | ldap_msgfree(result); |
| 4146 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4147 | } |
| 4148 | |
| 4149 | cn = get_single_attribute(mem_ctx, ld, entry, |
| 4150 | LDAP_ATTRIBUTE_ASSOCIATED_DOMAIN"associatedDomain"); |
| 4151 | if (cn == NULL((void*)0)) { |
| 4152 | ldap_msgfree(result); |
| 4153 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4154 | } |
| 4155 | |
| 4156 | *domain_name = cn; |
| 4157 | ldap_msgfree(result); |
| 4158 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4159 | } |
| 4160 | |
| 4161 | static NTSTATUS ipasam_get_enctypes(struct ipasam_private *ipasam_state, |
| 4162 | uint32_t *enctypes) |
| 4163 | { |
| 4164 | int ret; |
| 4165 | LDAPMessage *result; |
| 4166 | LDAPMessage *entry = NULL((void*)0); |
| 4167 | LDAP *ld = NULL((void*)0); |
| 4168 | int count, i; |
| 4169 | char **enctype_list, *dn; |
| 4170 | krb5_enctype enctype; |
| 4171 | krb5_error_code err; |
| 4172 | struct smbldap_state *ldap_state = ipasam_state->ldap_state; |
| 4173 | const char *attr_list[] = { |
| 4174 | "krbDefaultEncSaltTypes", |
| 4175 | NULL((void*)0) |
| 4176 | }; |
| 4177 | |
| 4178 | dn = talloc_asprintf(ipasam_state, "cn=%s,cn=kerberos,%s", |
| 4179 | ipasam_state->realm, |
| 4180 | ipasam_state->base_dn); |
| 4181 | |
| 4182 | if (dn == NULL((void*)0)) { |
| 4183 | DEBUG(1, ("Failed to construct DN to the realm's kerberos container\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4183", __FUNCTION__ )) && (dbgtext ("Failed to construct DN to the realm's kerberos container\n" )) ); |
| 4184 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4185 | } |
| 4186 | |
| 4187 | ret = smbldap_search(ldap_state, dn, LDAP_SCOPE_BASE((ber_int_t) 0x0000), |
| 4188 | "objectclass=krbrealmcontainer", attr_list, 0, |
| 4189 | &result); |
| 4190 | if (ret != LDAP_SUCCESS0x00) { |
| 4191 | DEBUG(1, ("Failed to get kerberos realm encryption types: %s\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4192", __FUNCTION__ )) && (dbgtext ("Failed to get kerberos realm encryption types: %s\n" , ldap_err2string (ret))) ) |
| 4192 | ldap_err2string (ret)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4192", __FUNCTION__ )) && (dbgtext ("Failed to get kerberos realm encryption types: %s\n" , ldap_err2string (ret))) ); |
| 4193 | talloc_free(dn)_talloc_free(dn, "ipa_sam.c" ":" "4193"); |
| 4194 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4195 | } |
| 4196 | |
| 4197 | ld = _smbldap_get_ldap(ldap_state); |
| 4198 | count = ldap_count_entries(ld, result); |
| 4199 | |
| 4200 | if (count != 1) { |
| 4201 | DEBUG(1, ("Unexpected number of results [%d] for realm "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4202", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for realm " "search.\n", count)) ) |
| 4202 | "search.\n", count))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4202", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for realm " "search.\n", count)) ); |
| 4203 | ldap_msgfree(result); |
| 4204 | talloc_free(dn)_talloc_free(dn, "ipa_sam.c" ":" "4204"); |
| 4205 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4206 | } |
| 4207 | |
| 4208 | entry = ldap_first_entry(ld, result); |
| 4209 | if (entry == NULL((void*)0)) { |
| 4210 | DEBUG(0, ("Could not get krbrealmcontainer entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4210", __FUNCTION__ )) && (dbgtext ("Could not get krbrealmcontainer entry\n" )) ); |
| 4211 | ldap_msgfree(result); |
| 4212 | talloc_free(dn)_talloc_free(dn, "ipa_sam.c" ":" "4212"); |
| 4213 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4214 | } |
| 4215 | |
| 4216 | enctype_list = get_attribute_values(dn, ld, entry, |
| 4217 | "krbDefaultEncSaltTypes", &count); |
| 4218 | ldap_msgfree(result); |
| 4219 | if (enctype_list == NULL((void*)0)) { |
| 4220 | talloc_free(dn)_talloc_free(dn, "ipa_sam.c" ":" "4220"); |
| 4221 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4222 | } |
| 4223 | |
| 4224 | *enctypes = 0; |
| 4225 | for (i = 0; i < count ; i++) { |
| 4226 | char *enc = strchr(enctype_list[i], ':'); |
| 4227 | if (enc != NULL((void*)0)) { |
| 4228 | *enc = '\0'; |
| 4229 | } |
| 4230 | err = krb5_string_to_enctype(enctype_list[i], &enctype); |
| 4231 | if (enc != NULL((void*)0)) { |
| 4232 | *enc = ':'; |
| 4233 | } |
| 4234 | if (err) { |
| 4235 | continue; |
| 4236 | } |
| 4237 | switch (enctype) { |
| 4238 | case ENCTYPE_DES_CBC_CRC0x0001: |
| 4239 | *enctypes |= KERB_ENCTYPE_DES_CBC_CRC( 0x00000001 ); |
| 4240 | break; |
| 4241 | case ENCTYPE_DES_CBC_MD50x0003: |
| 4242 | *enctypes |= KERB_ENCTYPE_DES_CBC_MD5( 0x00000002 ); |
| 4243 | break; |
| 4244 | case ENCTYPE_ARCFOUR_HMAC0x0017: |
| 4245 | if (!ipasam_state->fips_enabled) { |
| 4246 | *enctypes |= KERB_ENCTYPE_RC4_HMAC_MD5( 0x00000004 ); |
| 4247 | } |
| 4248 | break; |
| 4249 | case ENCTYPE_AES128_CTS_HMAC_SHA1_960x0011: |
| 4250 | *enctypes |= KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96( 0x00000008 ); |
| 4251 | break; |
| 4252 | case ENCTYPE_AES256_CTS_HMAC_SHA1_960x0012: |
| 4253 | *enctypes |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96( 0x00000010 ); |
| 4254 | break; |
| 4255 | default: |
| 4256 | break; |
| 4257 | } |
| 4258 | } |
| 4259 | |
| 4260 | talloc_free(dn)_talloc_free(dn, "ipa_sam.c" ":" "4260"); |
| 4261 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4262 | } |
| 4263 | |
| 4264 | static NTSTATUS ipasam_get_realm(struct ipasam_private *ipasam_state, |
| 4265 | char **realm) |
| 4266 | { |
| 4267 | int ret; |
| 4268 | LDAPMessage *result; |
| 4269 | LDAPMessage *entry = NULL((void*)0); |
| 4270 | LDAP *ld = NULL((void*)0); |
| 4271 | int count; |
| 4272 | char *cn; |
| 4273 | struct smbldap_state *ldap_state = ipasam_state->ldap_state; |
| 4274 | const char *attr_list[] = { |
| 4275 | "cn", |
| 4276 | NULL((void*)0) |
| 4277 | }; |
| 4278 | |
| 4279 | ret = smbldap_search(ldap_state, |
| 4280 | ipasam_state->base_dn, |
| 4281 | LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), |
| 4282 | "objectclass=krbrealmcontainer", attr_list, 0, |
| 4283 | &result); |
| 4284 | if (ret != LDAP_SUCCESS0x00) { |
| 4285 | DEBUG(1, ("Failed to get realm: %s\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4286", __FUNCTION__ )) && (dbgtext ("Failed to get realm: %s\n", ldap_err2string (ret))) ) |
| 4286 | ldap_err2string (ret)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4286", __FUNCTION__ )) && (dbgtext ("Failed to get realm: %s\n", ldap_err2string (ret))) ); |
| 4287 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4288 | } |
| 4289 | |
| 4290 | ld = _smbldap_get_ldap(ldap_state); |
| 4291 | count = ldap_count_entries(ld, result); |
| 4292 | |
| 4293 | if (count != 1) { |
| 4294 | DEBUG(1, ("Unexpected number of results [%d] for realm "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4295", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for realm " "search.\n", count)) ) |
| 4295 | "search.\n", count))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4295", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for realm " "search.\n", count)) ); |
| 4296 | ldap_msgfree(result); |
| 4297 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4298 | } |
| 4299 | |
| 4300 | entry = ldap_first_entry(ld, result); |
| 4301 | if (entry == NULL((void*)0)) { |
| 4302 | DEBUG(0, ("Could not get krbrealmcontainer entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4302", __FUNCTION__ )) && (dbgtext ("Could not get krbrealmcontainer entry\n" )) ); |
| 4303 | ldap_msgfree(result); |
| 4304 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4305 | } |
| 4306 | |
| 4307 | cn = get_single_attribute(ipasam_state, ld, |
| 4308 | entry, |
| 4309 | "cn"); |
| 4310 | if (cn == NULL((void*)0)) { |
| 4311 | ldap_msgfree(result); |
| 4312 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4313 | } |
| 4314 | |
| 4315 | *realm = cn; |
| 4316 | ldap_msgfree(result); |
| 4317 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4318 | } |
| 4319 | |
| 4320 | #ifdef HAVE_PDB_ENUM_UPN_SUFFIXES1 |
| 4321 | static NTSTATUS ipasam_enum_upn_suffixes(struct pdb_methods *pdb_methods, |
| 4322 | TALLOC_CTX *mem_ctx, |
| 4323 | uint32_t *num_suffixes, |
| 4324 | char ***suffixes) |
| 4325 | { |
| 4326 | int ret; |
| 4327 | LDAPMessage *result; |
| 4328 | LDAPMessage *entry = NULL((void*)0); |
| 4329 | LDAP *ld = NULL((void*)0); |
| 4330 | int count, i; |
| 4331 | char *realmdomains_dn = NULL((void*)0); |
| 4332 | char **domains = NULL((void*)0); |
| 4333 | struct ipasam_private *ipasam_state; |
| 4334 | struct smbldap_state *ldap_state; |
| 4335 | const char *attr_list[] = { |
| 4336 | LDAP_ATTRIBUTE_ASSOCIATED_DOMAIN"associatedDomain", |
| 4337 | NULL((void*)0) |
| 4338 | }; |
| 4339 | |
| 4340 | if ((suffixes == NULL((void*)0)) || (num_suffixes == NULL((void*)0))) { |
| 4341 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4342 | } |
| 4343 | |
| 4344 | ipasam_state = talloc_get_type_abort(pdb_methods->private_data, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(pdb_methods-> private_data, "struct ipasam_private", "ipa_sam.c" ":" "4344" ); |
| 4345 | ldap_state = ipasam_state->ldap_state; |
| 4346 | |
| 4347 | realmdomains_dn = talloc_asprintf(mem_ctx, "%s,%s", LDAP_CN_REALM_DOMAINS"cn=Realm Domains,cn=ipa,cn=etc", |
| 4348 | ipasam_state->base_dn); |
| 4349 | if (realmdomains_dn == NULL((void*)0)) { |
| 4350 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 4351 | } |
| 4352 | |
| 4353 | ret = smbldap_search(ldap_state, |
| 4354 | realmdomains_dn, |
| 4355 | LDAP_SCOPE_BASE((ber_int_t) 0x0000), |
| 4356 | "objectclass=" LDAP_OBJ_DOMAINRELATED"domainRelatedObject", attr_list, 0, |
| 4357 | &result); |
| 4358 | if (ret != LDAP_SUCCESS0x00) { |
| 4359 | DEBUG(1, ("Failed to get list of realm domains: %s\n",(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4360", __FUNCTION__ )) && (dbgtext ("Failed to get list of realm domains: %s\n" , ldap_err2string (ret))) ) |
| 4360 | ldap_err2string (ret)))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4360", __FUNCTION__ )) && (dbgtext ("Failed to get list of realm domains: %s\n" , ldap_err2string (ret))) ); |
| 4361 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4362 | } |
| 4363 | |
| 4364 | ld = _smbldap_get_ldap(ldap_state); |
| 4365 | count = ldap_count_entries(ld, result); |
| 4366 | if (count != 1) { |
| 4367 | DEBUG(1, ("Unexpected number of results [%d] for realm domains "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4368", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for realm domains " "search.\n", count)) ) |
| 4368 | "search.\n", count))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4368", __FUNCTION__ )) && (dbgtext ("Unexpected number of results [%d] for realm domains " "search.\n", count)) ); |
| 4369 | ldap_msgfree(result); |
| 4370 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4371 | } |
| 4372 | |
| 4373 | entry = ldap_first_entry(ld, result); |
| 4374 | if (entry == NULL((void*)0)) { |
| 4375 | DEBUG(0, ("Could not get domainRelatedObject entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4375", __FUNCTION__ )) && (dbgtext ("Could not get domainRelatedObject entry\n" )) ); |
| 4376 | ldap_msgfree(result); |
| 4377 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4378 | } |
| 4379 | |
| 4380 | domains = get_attribute_values(mem_ctx, ld, entry, |
| 4381 | LDAP_ATTRIBUTE_ASSOCIATED_DOMAIN"associatedDomain", &count); |
| 4382 | if (domains == NULL((void*)0)) { |
| 4383 | ldap_msgfree(result); |
| 4384 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4385 | } |
| 4386 | |
| 4387 | /* Since associatedDomain has attributeType MUST, there must be at least one domain */ |
| 4388 | for (i = 0; i < count ; i++) { |
| 4389 | /* TODO: use comparison function friendly to IDN */ |
| 4390 | if (strcasecmp(ipasam_state->domain_name, domains[i]) == 0) { |
| 4391 | break; |
| 4392 | } |
| 4393 | } |
| 4394 | |
| 4395 | if (i < count) { |
| 4396 | /* If we found our primary domain in the list and it is alone, exit with empty list */ |
| 4397 | if (count == 1) { |
| 4398 | ldap_msgfree(result); |
| 4399 | talloc_free(domains)_talloc_free(domains, "ipa_sam.c" ":" "4399"); |
| 4400 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4401 | } |
| 4402 | |
| 4403 | talloc_free(domains[i])_talloc_free(domains[i], "ipa_sam.c" ":" "4403"); |
| 4404 | |
| 4405 | /* if i is not last element, move everything down */ |
| 4406 | if (i != (count - 1)) { |
| 4407 | memmove(domains + i, domains + i + 1, sizeof(char *) * (count - i - 1)); |
| 4408 | } |
| 4409 | |
| 4410 | /* we don't resize whole list, only reduce number of elements in it |
| 4411 | * since sizing down a single pointer will not reduce memory usage in talloc |
| 4412 | */ |
| 4413 | domains[count - 1] = NULL((void*)0); |
| 4414 | *suffixes = domains; |
| 4415 | *num_suffixes = count - 1; |
| 4416 | } else { |
| 4417 | /* There is no our primary domain in the list */ |
| 4418 | *suffixes = domains; |
| 4419 | *num_suffixes = count; |
| 4420 | } |
| 4421 | |
| 4422 | ldap_msgfree(result); |
| 4423 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4424 | } |
| 4425 | #endif /* HAVE_PDB_ENUM_UPN_SUFFIXES */ |
| 4426 | |
| 4427 | |
| 4428 | #define SECRETS_DOMAIN_SID"SECRETS/SID" "SECRETS/SID" |
| 4429 | static char *sec_key(TALLOC_CTX *mem_ctx, const char *d) |
| 4430 | { |
| 4431 | char *tmp; |
| 4432 | char *res; |
| 4433 | |
| 4434 | tmp = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_DOMAIN_SID"SECRETS/SID", d); |
| 4435 | res = talloc_strdup_upper(mem_ctx, tmp); |
| 4436 | talloc_free(tmp)_talloc_free(tmp, "ipa_sam.c" ":" "4436"); |
| 4437 | |
| 4438 | return res; |
| 4439 | } |
| 4440 | |
| 4441 | static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state) |
| 4442 | { |
| 4443 | char hostname[255]; |
| 4444 | int ret; |
| 4445 | char *p; |
| 4446 | TALLOC_CTX *tmp_ctx; |
| 4447 | NTSTATUS status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
Value stored to 'status' during its initialization is never read | |
| 4448 | |
| 4449 | tmp_ctx =talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "ipa_sam.c" ":" "4449"); |
| 4450 | if (tmp_ctx == NULL((void*)0)) { |
| 4451 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 4452 | } |
| 4453 | |
| 4454 | if (!secrets_store(sec_key(tmp_ctx, ipasam_state->domain_name), |
| 4455 | &ipasam_state->domain_sid, sizeof(struct dom_sid))) { |
| 4456 | DEBUG(1, ("Failed to store domain SID"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4456", __FUNCTION__ )) && (dbgtext ("Failed to store domain SID")) ); |
| 4457 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4458 | goto done; |
| 4459 | } |
| 4460 | |
| 4461 | if (!secrets_store(sec_key(tmp_ctx, |
| 4462 | ipasam_state->flat_name), |
| 4463 | &ipasam_state->domain_sid, sizeof(struct dom_sid))) { |
| 4464 | DEBUG(1, ("Failed to store domain SID"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4464", __FUNCTION__ )) && (dbgtext ("Failed to store domain SID")) ); |
| 4465 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4466 | goto done; |
| 4467 | } |
| 4468 | |
| 4469 | ret = gethostname(hostname, sizeof(hostname)); |
| 4470 | if (ret == -1) { |
| 4471 | DEBUG(1, ("gethostname failed.\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4471", __FUNCTION__ )) && (dbgtext ("gethostname failed.\n")) ); |
| 4472 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4473 | goto done; |
| 4474 | } |
| 4475 | hostname[sizeof(hostname)-1] = '\0'; |
| 4476 | p = strchr(hostname, '.'); |
| 4477 | if (p != NULL((void*)0)) { |
| 4478 | *p = '\0'; |
| 4479 | } |
| 4480 | |
| 4481 | if (!secrets_store(sec_key(tmp_ctx, hostname), |
| 4482 | &ipasam_state->domain_sid, sizeof(struct dom_sid))) { |
| 4483 | DEBUG(1, ("Failed to store domain SID"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4483", __FUNCTION__ )) && (dbgtext ("Failed to store domain SID")) ); |
| 4484 | status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4485 | goto done; |
| 4486 | } |
| 4487 | |
| 4488 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4489 | |
| 4490 | done: |
| 4491 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "ipa_sam.c" ":" "4491"); |
| 4492 | return status; |
| 4493 | } |
| 4494 | |
| 4495 | struct ipasam_sasl_interact_priv { |
| 4496 | krb5_context context; |
| 4497 | krb5_principal principal; |
| 4498 | krb5_keytab keytab; |
| 4499 | krb5_get_init_creds_opt *options; |
| 4500 | krb5_creds creds; |
| 4501 | krb5_ccache ccache; |
| 4502 | const char *name; |
| 4503 | int name_len; |
| 4504 | }; |
| 4505 | |
| 4506 | static int ldap_sasl_interact(LDAP *ld, unsigned flags, void *priv_data, void *sit) |
| 4507 | { |
| 4508 | sasl_interact_t *in = NULL((void*)0); |
| 4509 | int ret = LDAP_OTHER0x50; |
| 4510 | struct ipasam_sasl_interact_priv *data = (struct ipasam_sasl_interact_priv*) priv_data; |
| 4511 | |
| 4512 | if (!ld) return LDAP_PARAM_ERROR(-9); |
| 4513 | |
| 4514 | for (in = sit; in && in->id != SASL_CB_LIST_END0; in++) { |
| 4515 | switch(in->id) { |
| 4516 | case SASL_CB_USER0x4001: |
| 4517 | in->result = data->name; |
| 4518 | in->len = data->name_len; |
| 4519 | ret = LDAP_SUCCESS0x00; |
| 4520 | break; |
| 4521 | case SASL_CB_GETREALM(0x4008): |
| 4522 | in->result = data->principal->realm.data; |
| 4523 | in->len = data->principal->realm.length; |
| 4524 | ret = LDAP_SUCCESS0x00; |
| 4525 | break; |
| 4526 | default: |
| 4527 | in->result = NULL((void*)0); |
| 4528 | in->len = 0; |
| 4529 | ret = LDAP_OTHER0x50; |
| 4530 | } |
| 4531 | } |
| 4532 | return ret; |
| 4533 | } |
| 4534 | |
| 4535 | |
| 4536 | static void bind_callback_cleanup_creds(struct ipasam_sasl_interact_priv *datap) { |
| 4537 | krb5_free_cred_contents(datap->context, &datap->creds); |
| 4538 | |
| 4539 | if (datap->options) { |
| 4540 | krb5_get_init_creds_opt_free(datap->context, datap->options); |
| 4541 | datap->options = NULL((void*)0); |
| 4542 | } |
| 4543 | } |
| 4544 | |
| 4545 | static void bind_callback_cleanup(struct ipasam_sasl_interact_priv *datap, krb5_error_code rc) { |
| 4546 | const char *errstring = NULL((void*)0); |
| 4547 | |
| 4548 | if (!datap->context) { |
| 4549 | return; |
| 4550 | } |
| 4551 | |
| 4552 | if (rc) { |
| 4553 | errstring = krb5_get_error_message(datap->context, rc); |
| 4554 | DEBUG(0,("kerberos error: code=%d, message=%s\n", rc, errstring))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4554", __FUNCTION__ )) && (dbgtext ("kerberos error: code=%d, message=%s\n" , rc, errstring)) ); |
| 4555 | krb5_free_error_message(datap->context, errstring); |
| 4556 | } |
| 4557 | |
| 4558 | bind_callback_cleanup_creds(datap); |
| 4559 | |
| 4560 | if (datap->keytab) { |
| 4561 | krb5_kt_close(datap->context, datap->keytab); |
| 4562 | datap->keytab = NULL((void*)0); |
| 4563 | } |
| 4564 | |
| 4565 | if (datap->ccache) { |
| 4566 | krb5_cc_close(datap->context, datap->ccache); |
| 4567 | datap->ccache = NULL((void*)0); |
| 4568 | } |
| 4569 | |
| 4570 | if (datap->principal) { |
| 4571 | krb5_free_principal(datap->context, datap->principal); |
| 4572 | datap->principal = NULL((void*)0); |
| 4573 | } |
| 4574 | |
| 4575 | krb5_free_context(datap->context); |
| 4576 | datap->context = NULL((void*)0); |
| 4577 | } |
| 4578 | |
| 4579 | static krb5_error_code bind_callback_obtain_creds(struct ipasam_sasl_interact_priv *datap) { |
| 4580 | krb5_error_code rc; |
| 4581 | |
| 4582 | rc = krb5_get_init_creds_opt_alloc(datap->context, &datap->options); |
| 4583 | if (rc) { |
| 4584 | return rc; |
| 4585 | } |
| 4586 | |
| 4587 | rc = krb5_get_init_creds_opt_set_out_ccache(datap->context, datap->options, datap->ccache); |
| 4588 | if (rc) { |
| 4589 | return rc; |
| 4590 | } |
| 4591 | |
| 4592 | rc = krb5_get_init_creds_keytab(datap->context, &datap->creds, datap->principal, datap->keytab, |
| 4593 | 0, NULL((void*)0), datap->options); |
| 4594 | return rc; |
| 4595 | } |
| 4596 | |
| 4597 | extern const char * lp_dedicated_keytab_file(void); |
| 4598 | static int bind_callback(LDAP *ldap_struct, struct smbldap_state *ldap_state, void* ipasam_priv) { |
| 4599 | krb5_error_code rc; |
| 4600 | krb5_creds *out_creds = NULL((void*)0); |
| 4601 | krb5_creds in_creds; |
| 4602 | |
| 4603 | struct ipasam_sasl_interact_priv data; |
| 4604 | struct ipasam_private *ipasam_state = NULL((void*)0); |
| 4605 | int ret; |
| 4606 | |
| 4607 | memset(&data, 0, sizeof(struct ipasam_sasl_interact_priv)); |
| 4608 | memset(&in_creds, 0, sizeof(krb5_creds)); |
| 4609 | |
| 4610 | ipasam_state = talloc_get_type_abort(ipasam_priv, struct ipasam_private)(struct ipasam_private *)_talloc_get_type_abort(ipasam_priv, "struct ipasam_private" , "ipa_sam.c" ":" "4610"); |
| 4611 | |
| 4612 | if ((ipasam_state->client_princ == NULL((void*)0)) || |
| 4613 | (ipasam_state->server_princ == NULL((void*)0))) { |
| 4614 | DEBUG(0, ("bind_callback: ipasam service principals are not set, cannot use GSSAPI bind\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4614", __FUNCTION__ )) && (dbgtext ("bind_callback: ipasam service principals are not set, cannot use GSSAPI bind\n" )) ); |
| 4615 | return LDAP_LOCAL_ERROR(-2); |
| 4616 | } |
| 4617 | |
| 4618 | data.name = ipasam_state->client_princ; |
| 4619 | data.name_len = strlen(data.name); |
| 4620 | |
| 4621 | rc = krb5_init_context(&data.context); |
| 4622 | if (rc) { |
| 4623 | return LDAP_LOCAL_ERROR(-2); |
| 4624 | } |
| 4625 | |
| 4626 | rc = krb5_parse_name(data.context, data.name, &data.principal); |
| 4627 | if (rc) { |
| 4628 | bind_callback_cleanup(&data, rc); |
| 4629 | return LDAP_LOCAL_ERROR(-2); |
| 4630 | } |
| 4631 | |
| 4632 | rc = krb5_cc_default(data.context, &data.ccache); |
| 4633 | |
| 4634 | if (rc) { |
| 4635 | bind_callback_cleanup(&data, rc); |
| 4636 | return LDAP_LOCAL_ERROR(-2); |
| 4637 | } |
| 4638 | |
| 4639 | rc = krb5_kt_resolve(data.context, lp_dedicated_keytab_file(), &data.keytab); |
| 4640 | if (rc) { |
| 4641 | bind_callback_cleanup(&data, rc); |
| 4642 | return LDAP_LOCAL_ERROR(-2); |
| 4643 | } |
| 4644 | |
| 4645 | rc = krb5_parse_name(data.context, ipasam_state->client_princ, &in_creds.client); |
| 4646 | if (rc) { |
| 4647 | krb5_free_principal(data.context, data.creds.client); |
| 4648 | bind_callback_cleanup(&data, rc); |
| 4649 | return LDAP_LOCAL_ERROR(-2); |
| 4650 | } |
| 4651 | |
| 4652 | rc = krb5_parse_name(data.context, ipasam_state->server_princ, &in_creds.server); |
| 4653 | if (rc) { |
| 4654 | krb5_free_principal(data.context, in_creds.server); |
| 4655 | bind_callback_cleanup(&data, rc); |
| 4656 | return LDAP_LOCAL_ERROR(-2); |
| 4657 | } |
| 4658 | |
| 4659 | rc = krb5_get_credentials(data.context, KRB5_GC_CACHED2, data.ccache, &in_creds, &out_creds); |
| 4660 | krb5_free_principal(data.context, in_creds.server); |
| 4661 | krb5_free_principal(data.context, in_creds.client); |
| 4662 | |
| 4663 | if (rc != 0 && rc != KRB5KRB_AP_ERR_TKT_NYV(-1765328351L) && rc != KRB5KRB_AP_ERR_TKT_EXPIRED(-1765328352L)) { |
| 4664 | rc = bind_callback_obtain_creds(&data); |
| 4665 | if (rc) { |
| 4666 | bind_callback_cleanup(&data, rc); |
| 4667 | return LDAP_LOCAL_ERROR(-2); |
| 4668 | } |
| 4669 | } |
| 4670 | |
| 4671 | ret = ldap_sasl_interactive_bind_s(ldap_struct, |
| 4672 | NULL((void*)0), "GSSAPI", |
| 4673 | NULL((void*)0), NULL((void*)0), |
| 4674 | LDAP_SASL_QUIET2U, |
| 4675 | ldap_sasl_interact, &data); |
| 4676 | |
| 4677 | /* By now we have 'ret' for LDAP result and 'rc' for Kerberos result |
| 4678 | * if LDAP_API_ERROR(ret) is true, LDAP server rejected our ccache. There may be several issues: |
| 4679 | * |
| 4680 | * 1. Credentials are invalid due to outdated ccache leftover from previous install or ticket is from future |
| 4681 | * Wipe out old ccache and start again |
| 4682 | * |
| 4683 | * 2. Key in the keytab is not enough to obtain ticket for cifs/FQDN@REALM service |
| 4684 | * Cannot continue without proper keytab |
| 4685 | * |
| 4686 | * Only process (1) because (2) and other errors will be taken care of by smbd after multiple retries. |
| 4687 | * |
| 4688 | * Since both smbd and winbindd will use this passdb module, on startup both will try to access the same |
| 4689 | * ccache. It may happen that if ccache was missing or contained invalid cached credentials, that one of |
| 4690 | * them will complain loudly about missing ccache file at the time when the other one will be creating |
| 4691 | * a new ccache file by the above call of bind_callback_obtain_creds(). This is expected and correct behavior. |
| 4692 | * |
| 4693 | */ |
| 4694 | |
| 4695 | if (LDAP_API_ERROR(ret)((ret)<0) && |
| 4696 | ((rc == 0) || (rc == KRB5KRB_AP_ERR_TKT_NYV(-1765328351L)) || (rc == KRB5KRB_AP_ERR_TKT_EXPIRED(-1765328352L)))) { |
| 4697 | bind_callback_cleanup_creds(&data); |
| 4698 | rc = bind_callback_obtain_creds(&data); |
| 4699 | if (rc) { |
| 4700 | bind_callback_cleanup(&data, rc); |
| 4701 | return LDAP_LOCAL_ERROR(-2); |
| 4702 | } |
| 4703 | ret = ldap_sasl_interactive_bind_s(ldap_struct, |
| 4704 | NULL((void*)0), "GSSAPI", |
| 4705 | NULL((void*)0), NULL((void*)0), |
| 4706 | LDAP_SASL_QUIET2U, |
| 4707 | ldap_sasl_interact, &data); |
| 4708 | } |
| 4709 | |
| 4710 | if (LDAP_SECURITY_ERROR(ret)(((0x2F) <= ((ret))) && (((ret)) <= (0x32)))) { |
| 4711 | DEBUG(0, ("bind_callback: cannot perform interactive SASL bind with GSSAPI. LDAP security error is %d\n", ret))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4711", __FUNCTION__ )) && (dbgtext ("bind_callback: cannot perform interactive SASL bind with GSSAPI. LDAP security error is %d\n" , ret)) ); |
| 4712 | } |
| 4713 | |
| 4714 | if (out_creds) { |
| 4715 | krb5_free_creds(data.context, out_creds); |
| 4716 | } |
| 4717 | bind_callback_cleanup(&data, 0); |
| 4718 | return ret; |
| 4719 | } |
| 4720 | |
| 4721 | static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state) { |
| 4722 | |
| 4723 | krb5_error_code rc; |
| 4724 | int ret; |
| 4725 | krb5_context context; |
| 4726 | NTSTATUS status = NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4727 | char hostname[255]; |
| 4728 | char *default_realm = NULL((void*)0); |
| 4729 | |
| 4730 | if (!ipasam_state) { |
| 4731 | return status; |
| 4732 | } |
| 4733 | |
| 4734 | rc = krb5_init_context(&context); |
| 4735 | if (rc) { |
| 4736 | return status; |
| 4737 | } |
| 4738 | |
| 4739 | ret = gethostname(hostname, sizeof(hostname)); |
| 4740 | if (ret == -1) { |
| 4741 | DEBUG(1, ("gethostname failed.\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4741", __FUNCTION__ )) && (dbgtext ("gethostname failed.\n")) ); |
| 4742 | goto done; |
| 4743 | } |
| 4744 | hostname[sizeof(hostname)-1] = '\0'; |
| 4745 | |
| 4746 | rc = krb5_get_default_realm(context, &default_realm); |
| 4747 | if (rc) { |
| 4748 | goto done; |
| 4749 | }; |
| 4750 | |
| 4751 | if (ipasam_state->client_princ) { |
| 4752 | talloc_free(ipasam_state->client_princ)_talloc_free(ipasam_state->client_princ, "ipa_sam.c" ":" "4752" ); |
| 4753 | ipasam_state->client_princ = NULL((void*)0); |
| 4754 | } |
| 4755 | |
| 4756 | ipasam_state->client_princ = talloc_asprintf(ipasam_state, |
| 4757 | "cifs/%s@%s", |
| 4758 | hostname, |
| 4759 | default_realm); |
| 4760 | |
| 4761 | if (ipasam_state->client_princ == NULL((void*)0)) { |
| 4762 | DEBUG(0, ("Failed to create ipasam client principal.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4762", __FUNCTION__ )) && (dbgtext ("Failed to create ipasam client principal.\n" )) ); |
| 4763 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 4764 | goto done; |
| 4765 | } |
| 4766 | |
| 4767 | if (ipasam_state->server_princ) { |
| 4768 | talloc_free(ipasam_state->server_princ)_talloc_free(ipasam_state->server_princ, "ipa_sam.c" ":" "4768" ); |
| 4769 | ipasam_state->server_princ = NULL((void*)0); |
| 4770 | } |
| 4771 | |
| 4772 | ipasam_state->server_princ = talloc_asprintf(ipasam_state, |
| 4773 | "ldap/%s@%s", |
| 4774 | hostname, |
| 4775 | default_realm); |
| 4776 | |
| 4777 | if (ipasam_state->server_princ == NULL((void*)0)) { |
| 4778 | DEBUG(0, ("Failed to create ipasam server principal.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4778", __FUNCTION__ )) && (dbgtext ("Failed to create ipasam server principal.\n" )) ); |
| 4779 | status = NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 4780 | goto done; |
| 4781 | } |
| 4782 | |
| 4783 | status = NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 4784 | |
| 4785 | done: |
| 4786 | |
| 4787 | if (default_realm) { |
| 4788 | krb5_free_default_realm(context, default_realm); |
| 4789 | } |
| 4790 | |
| 4791 | if (context) { |
| 4792 | krb5_free_context(context); |
| 4793 | } |
| 4794 | return status; |
| 4795 | } |
| 4796 | |
| 4797 | static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method, |
| 4798 | const char *location) |
| 4799 | { |
| 4800 | struct ipasam_private *ipasam_state; |
| 4801 | |
| 4802 | char *uri; |
| 4803 | NTSTATUS status; |
| 4804 | char *dn = NULL((void*)0); |
| 4805 | char *domain_sid_string = NULL((void*)0); |
| 4806 | struct dom_sid *ldap_domain_sid = NULL((void*)0); |
| 4807 | struct dom_sid *fallback_group_sid = NULL((void*)0); |
| 4808 | char *fallback_group_gid_str = NULL((void*)0); |
| 4809 | |
| 4810 | LDAPMessage *result = NULL((void*)0); |
| 4811 | LDAPMessage *entry = NULL((void*)0); |
| 4812 | enum idmap_error_code err; |
| 4813 | uint32_t enctypes = 0; |
| 4814 | |
| 4815 | status = make_pdb_method(pdb_method); |
| 4816 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4817 | return status; |
| 4818 | } |
| 4819 | |
| 4820 | (*pdb_method)->name = "ipasam"; |
| 4821 | |
| 4822 | if ( !(ipasam_state = talloc_zero(*pdb_method, struct ipasam_private)(struct ipasam_private *)_talloc_zero(*pdb_method, sizeof(struct ipasam_private), "struct ipasam_private")) ) { |
| 4823 | DEBUG(0, ("pdb_init_ipasam: talloc() failed for ipasam private_data!\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4823", __FUNCTION__ )) && (dbgtext ("pdb_init_ipasam: talloc() failed for ipasam private_data!\n" )) ); |
| 4824 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 4825 | } |
| 4826 | |
| 4827 | uri = talloc_strdup(ipasam_state, location ); |
| 4828 | if (uri == NULL((void*)0)) { |
| 4829 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 4830 | } |
| 4831 | trim_string( uri, "\"", "\"" ); |
| 4832 | |
| 4833 | status = ipasam_generate_principals(ipasam_state); |
| 4834 | |
| 4835 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4836 | DEBUG(0, ("Failed to generate kerberos principal for LDAP authentication.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4836", __FUNCTION__ )) && (dbgtext ("Failed to generate kerberos principal for LDAP authentication.\n" )) ); |
| 4837 | return status; |
| 4838 | } else { |
| 4839 | /* We authenticate via GSSAPI and thus will use kerberos principal to bind our access */ |
| 4840 | status = smbldap_init(*pdb_method, pdb_get_tevent_context(), |
| 4841 | uri, false0, NULL((void*)0), NULL((void*)0), |
| 4842 | &ipasam_state->ldap_state); |
| 4843 | if (NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4844 | #ifdef HAVE_SMBLDAP_SET_BIND_CALLBACK1 |
| 4845 | smbldap_set_bind_callback(ipasam_state->ldap_state, bind_callback, ipasam_state); |
| 4846 | #else |
| 4847 | ipasam_state->ldap_state->bind_callback = bind_callback; |
| 4848 | ipasam_state->ldap_state->bind_callback_data = ipasam_state; |
| 4849 | #endif |
| 4850 | } |
| 4851 | } |
| 4852 | |
| 4853 | talloc_free(uri)_talloc_free(uri, "ipa_sam.c" ":" "4853"); |
| 4854 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4855 | return status; |
| 4856 | } |
| 4857 | |
| 4858 | (*pdb_method)->private_data = ipasam_state; |
| 4859 | (*pdb_method)->free_private_data = ipasam_free_private_data; |
| 4860 | |
| 4861 | status = ipasam_get_base_dn(ipasam_state->ldap_state, |
| 4862 | ipasam_state, |
| 4863 | &ipasam_state->base_dn); |
| 4864 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4865 | DEBUG(0, ("Failed to get base DN.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4865", __FUNCTION__ )) && (dbgtext ("Failed to get base DN.\n")) ); |
| 4866 | return status; |
| 4867 | } |
| 4868 | |
| 4869 | if (!(smbldap_has_extension(priv2ld(ipasam_state), IPA_KEYTAB_SET_OID"2.16.840.1.113730.3.8.10.1") || |
| 4870 | smbldap_has_extension(priv2ld(ipasam_state), IPA_KEYTAB_SET_OID_OLD"2.16.840.1.113730.3.8.3.1"))) { |
| 4871 | DEBUG(0, ("Server is not an IPA server.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4871", __FUNCTION__ )) && (dbgtext ("Server is not an IPA server.\n")) ); |
| 4872 | return NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 4873 | } |
| 4874 | |
| 4875 | ipasam_state->fips_enabled = ipapwd_fips_enabled(); |
| 4876 | ipasam_state->trust_dn = talloc_asprintf(ipasam_state, |
| 4877 | "cn=ad,cn=trusts,%s", |
| 4878 | ipasam_state->base_dn); |
| 4879 | if (ipasam_state->trust_dn == NULL((void*)0)) { |
| 4880 | DEBUG(0, ("Failed to create trsut DN.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4880", __FUNCTION__ )) && (dbgtext ("Failed to create trsut DN.\n")) ); |
| 4881 | return NT_STATUS_NO_MEMORY((NTSTATUS) { 0xc0000017 }); |
| 4882 | } |
| 4883 | |
| 4884 | status = ipasam_get_domain_name(ipasam_state, ipasam_state, |
| 4885 | (char**) &ipasam_state->domain_name); |
| 4886 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4887 | DEBUG(0, ("Failed to get domain name.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4887", __FUNCTION__ )) && (dbgtext ("Failed to get domain name.\n")) ); |
| 4888 | return status; |
| 4889 | } |
| 4890 | |
| 4891 | status = ipasam_get_realm(ipasam_state, |
| 4892 | &ipasam_state->realm); |
| 4893 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4894 | DEBUG(0, ("Failed to get realm.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4894", __FUNCTION__ )) && (dbgtext ("Failed to get realm.\n")) ); |
| 4895 | return status; |
| 4896 | } |
| 4897 | |
| 4898 | status = ipasam_search_domain_info(ipasam_state->ldap_state, &result); |
| 4899 | |
| 4900 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4901 | DEBUG(0, ("pdb_init_ldapsam: WARNING: Could not get domain "(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4903", __FUNCTION__ )) && (dbgtext ("pdb_init_ldapsam: WARNING: Could not get domain " "info, nor add one to the domain. " "We cannot work reliably without it.\n" )) ) |
| 4902 | "info, nor add one to the domain. "(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4903", __FUNCTION__ )) && (dbgtext ("pdb_init_ldapsam: WARNING: Could not get domain " "info, nor add one to the domain. " "We cannot work reliably without it.\n" )) ) |
| 4903 | "We cannot work reliably without it.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4903", __FUNCTION__ )) && (dbgtext ("pdb_init_ldapsam: WARNING: Could not get domain " "info, nor add one to the domain. " "We cannot work reliably without it.\n" )) ); |
| 4904 | return NT_STATUS_CANT_ACCESS_DOMAIN_INFO((NTSTATUS) { 0xc00000da }); |
| 4905 | } |
| 4906 | |
| 4907 | entry = ldap_first_entry(priv2ld(ipasam_state), result); |
| 4908 | if (entry == NULL((void*)0)) { |
| 4909 | DEBUG(0, ("pdb_init_ipasam: Could not get domain info "(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4910", __FUNCTION__ )) && (dbgtext ("pdb_init_ipasam: Could not get domain info " "entry\n")) ) |
| 4910 | "entry\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4910", __FUNCTION__ )) && (dbgtext ("pdb_init_ipasam: Could not get domain info " "entry\n")) ); |
| 4911 | ldap_msgfree(result); |
| 4912 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4913 | } |
| 4914 | |
| 4915 | dn = get_dn(ipasam_state, priv2ld(ipasam_state), entry); |
| 4916 | if (dn == NULL((void*)0)) { |
| 4917 | ldap_msgfree(result); |
| 4918 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4919 | } |
| 4920 | |
| 4921 | ipasam_state->domain_dn = smb_xstrdup(dn); |
| 4922 | talloc_free(dn)_talloc_free(dn, "ipa_sam.c" ":" "4922"); |
| 4923 | |
| 4924 | ipasam_state->flat_name = get_single_attribute(ipasam_state, |
| 4925 | priv2ld(ipasam_state), |
| 4926 | entry, |
| 4927 | LDAP_ATTRIBUTE_FLAT_NAME"ipaNTFlatName"); |
| 4928 | if (ipasam_state->flat_name == NULL((void*)0)) { |
| 4929 | DEBUG(0, ("Missing mandatory attribute %s.\n",(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4930", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "ipaNTFlatName")) ) |
| 4930 | LDAP_ATTRIBUTE_FLAT_NAME))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4930", __FUNCTION__ )) && (dbgtext ("Missing mandatory attribute %s.\n", "ipaNTFlatName")) ); |
| 4931 | ldap_msgfree(result); |
| 4932 | return NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 4933 | } |
| 4934 | |
| 4935 | err = sss_idmap_init(idmap_talloc, ipasam_state, |
| 4936 | idmap_talloc_free, |
| 4937 | &ipasam_state->idmap_ctx); |
| 4938 | if (err != IDMAP_SUCCESS) { |
| 4939 | DEBUG(1, ("Failed to setup idmap context.\n"))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4939", __FUNCTION__ )) && (dbgtext ("Failed to setup idmap context.\n")) ); |
| 4940 | ldap_msgfree(result); |
| 4941 | return NT_STATUS_UNSUCCESSFUL((NTSTATUS) { 0xc0000001 }); |
| 4942 | } |
| 4943 | |
| 4944 | fallback_group_sid = get_fallback_group_sid(ipasam_state, |
| 4945 | ipasam_state->ldap_state, |
| 4946 | ipasam_state->idmap_ctx, |
| 4947 | result, |
| 4948 | &fallback_group_gid_str); |
| 4949 | if (fallback_group_sid == NULL((void*)0)) { |
| 4950 | DEBUG(0, ("Cannot find SID of fallback group.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4950", __FUNCTION__ )) && (dbgtext ("Cannot find SID of fallback group.\n" )) ); |
| 4951 | ldap_msgfree(result); |
| 4952 | return NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 4953 | } |
| 4954 | sid_copy(&ipasam_state->fallback_primary_group, fallback_group_sid); |
| 4955 | talloc_free(fallback_group_sid)_talloc_free(fallback_group_sid, "ipa_sam.c" ":" "4955"); |
| 4956 | |
| 4957 | if (fallback_group_gid_str == NULL((void*)0)) { |
| 4958 | DEBUG(0, ("Cannot find gidNumber of fallback group.\n"))(void)( ((0) <= 1000) && (debuglevel_get_class(0) >= (0)) && (dbghdrclass( 0, 0, "ipa_sam.c" ":" "4958", __FUNCTION__ )) && (dbgtext ("Cannot find gidNumber of fallback group.\n" )) ); |
| 4959 | ldap_msgfree(result); |
| 4960 | return NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 4961 | } |
| 4962 | ipasam_state->fallback_primary_group_gid_str = fallback_group_gid_str; |
| 4963 | |
| 4964 | domain_sid_string = get_single_attribute(ipasam_state, |
| 4965 | priv2ld(ipasam_state), |
| 4966 | entry, |
| 4967 | LDAP_ATTRIBUTE_SID"ipaNTSecurityIdentifier"); |
| 4968 | |
| 4969 | if (domain_sid_string) { |
| 4970 | err = sss_idmap_sid_to_smb_sid(ipasam_state->idmap_ctx, |
| 4971 | domain_sid_string, |
| 4972 | &ldap_domain_sid); |
| 4973 | if (err != IDMAP_SUCCESS) { |
| 4974 | DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4975", __FUNCTION__ )) && (dbgtext ("pdb_init_ldapsam: SID [%s] could not be " "read as a valid SID\n", domain_sid_string)) ) |
| 4975 | "read as a valid SID\n", domain_sid_string))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "4975", __FUNCTION__ )) && (dbgtext ("pdb_init_ldapsam: SID [%s] could not be " "read as a valid SID\n", domain_sid_string)) ); |
| 4976 | ldap_msgfree(result); |
| 4977 | TALLOC_FREE(domain_sid_string)do { if (domain_sid_string != ((void*)0)) { _talloc_free(domain_sid_string , "ipa_sam.c" ":" "4977"); domain_sid_string=((void*)0); } } while (0); |
| 4978 | return NT_STATUS_INVALID_PARAMETER((NTSTATUS) { 0xc000000d }); |
| 4979 | } |
| 4980 | sid_copy(&ipasam_state->domain_sid, ldap_domain_sid); |
| 4981 | talloc_free(ldap_domain_sid)_talloc_free(ldap_domain_sid, "ipa_sam.c" ":" "4981"); |
| 4982 | talloc_free(domain_sid_string)_talloc_free(domain_sid_string, "ipa_sam.c" ":" "4982"); |
| 4983 | |
| 4984 | status = save_sid_to_secret(ipasam_state); |
| 4985 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4986 | ldap_msgfree(result); |
| 4987 | return status; |
| 4988 | } |
| 4989 | } |
| 4990 | |
| 4991 | ldap_msgfree(result); |
| 4992 | |
| 4993 | status = ipasam_get_enctypes(ipasam_state, |
| 4994 | &enctypes); |
| 4995 | |
| 4996 | if (!NT_STATUS_IS_OK(status)((((status).v) == 0))) { |
| 4997 | enctypes = KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96( 0x00000008 ) | |
| 4998 | KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96( 0x00000010 ); |
| 4999 | if (!ipasam_state->fips_enabled) { |
| 5000 | enctypes |= KERB_ENCTYPE_RC4_HMAC_MD5( 0x00000004 ); |
| 5001 | } |
| 5002 | } |
| 5003 | |
| 5004 | ipasam_state->supported_enctypes = enctypes; |
| 5005 | |
| 5006 | (*pdb_method)->getsampwnam = ipasam_getsampwnam; |
| 5007 | (*pdb_method)->getsampwsid = ipasam_getsampwsid; |
| 5008 | (*pdb_method)->search_users = ipasam_search_users; |
| 5009 | (*pdb_method)->search_groups = ipasam_search_groups; |
| 5010 | (*pdb_method)->search_aliases = ipasam_search_aliases; |
| 5011 | (*pdb_method)->lookup_rids = ldapsam_lookup_rids; |
| 5012 | (*pdb_method)->sid_to_id = ldapsam_sid_to_id; |
| 5013 | #if PASSDB_INTERFACE_VERSION25 >= 24 |
| 5014 | /* Since version 24, uid_to_sid() and gid_to_sid() were removed in favor of id_to_sid() */ |
| 5015 | (*pdb_method)->id_to_sid = ipasam_id_to_sid; |
| 5016 | #else |
| 5017 | (*pdb_method)->uid_to_sid = ipasam_uid_to_sid; |
| 5018 | (*pdb_method)->gid_to_sid = ipasam_gid_to_sid; |
| 5019 | #endif |
| 5020 | |
| 5021 | (*pdb_method)->capabilities = pdb_ipasam_capabilities; |
| 5022 | (*pdb_method)->get_domain_info = pdb_ipasam_get_domain_info; |
| 5023 | |
| 5024 | (*pdb_method)->get_trusteddom_pw = ipasam_get_trusteddom_pw; |
| 5025 | (*pdb_method)->set_trusteddom_pw = ipasam_set_trusteddom_pw; |
| 5026 | (*pdb_method)->del_trusteddom_pw = ipasam_del_trusteddom_pw; |
| 5027 | (*pdb_method)->enum_trusteddoms = ipasam_enum_trusteddoms; |
| 5028 | |
| 5029 | (*pdb_method)->get_trusted_domain = ipasam_get_trusted_domain; |
| 5030 | (*pdb_method)->get_trusted_domain_by_sid = ipasam_get_trusted_domain_by_sid; |
| 5031 | (*pdb_method)->set_trusted_domain = ipasam_set_trusted_domain; |
| 5032 | (*pdb_method)->del_trusted_domain = ipasam_del_trusted_domain; |
| 5033 | (*pdb_method)->enum_trusted_domains = ipasam_enum_trusted_domains; |
| 5034 | #ifdef HAVE_PDB_ENUM_UPN_SUFFIXES1 |
| 5035 | (*pdb_method)->enum_upn_suffixes = ipasam_enum_upn_suffixes; |
| 5036 | DEBUG(1, ("pdb_init_ipasam: support for pdb_enum_upn_suffixes "(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "5037", __FUNCTION__ )) && (dbgtext ("pdb_init_ipasam: support for pdb_enum_upn_suffixes " "enabled for domain %s\n", ipasam_state->domain_name)) ) |
| 5037 | "enabled for domain %s\n", ipasam_state->domain_name))(void)( ((1) <= 1000) && (debuglevel_get_class(0) >= (1)) && (dbghdrclass( 1, 0, "ipa_sam.c" ":" "5037", __FUNCTION__ )) && (dbgtext ("pdb_init_ipasam: support for pdb_enum_upn_suffixes " "enabled for domain %s\n", ipasam_state->domain_name)) ); |
| 5038 | #endif |
| 5039 | |
| 5040 | return NT_STATUS_OK((NTSTATUS) { 0x0 }); |
| 5041 | } |
| 5042 | |
| 5043 | NTSTATUS samba_module_init(void) |
| 5044 | { |
| 5045 | return smb_register_passdb(PASSDB_INTERFACE_VERSION25, "ipasam", |
| 5046 | pdb_init_ipasam); |
| 5047 | } |
| 5048 | |
| 5049 | NTSTATUS samba_init_module(void) |
| 5050 | { |
| 5051 | return smb_register_passdb(PASSDB_INTERFACE_VERSION25, "ipasam", |
| 5052 | pdb_init_ipasam); |
| 5053 | } |