1*ebfedea0SLionel Sambuc /* $NetBSD: ad.c,v 1.1.1.1 2011/04/13 18:15:29 elric Exp $ */ 2*ebfedea0SLionel Sambuc 3*ebfedea0SLionel Sambuc /* 4*ebfedea0SLionel Sambuc * Copyright (c) 2004 Kungliga Tekniska Högskolan 5*ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden). 6*ebfedea0SLionel Sambuc * All rights reserved. 7*ebfedea0SLionel Sambuc * 8*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without 9*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions 10*ebfedea0SLionel Sambuc * are met: 11*ebfedea0SLionel Sambuc * 12*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 13*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer. 14*ebfedea0SLionel Sambuc * 15*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 16*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 17*ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution. 18*ebfedea0SLionel Sambuc * 19*ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors 20*ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software 21*ebfedea0SLionel Sambuc * without specific prior written permission. 22*ebfedea0SLionel Sambuc * 23*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24*ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25*ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26*ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27*ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28*ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29*ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30*ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31*ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32*ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33*ebfedea0SLionel Sambuc * SUCH DAMAGE. 34*ebfedea0SLionel Sambuc */ 35*ebfedea0SLionel Sambuc 36*ebfedea0SLionel Sambuc #define HAVE_TSASL 1 37*ebfedea0SLionel Sambuc 38*ebfedea0SLionel Sambuc #include "kadm5_locl.h" 39*ebfedea0SLionel Sambuc #if 1 40*ebfedea0SLionel Sambuc #undef OPENLDAP 41*ebfedea0SLionel Sambuc #undef HAVE_TSASL 42*ebfedea0SLionel Sambuc #endif 43*ebfedea0SLionel Sambuc #ifdef OPENLDAP 44*ebfedea0SLionel Sambuc #include <ldap.h> 45*ebfedea0SLionel Sambuc #ifdef HAVE_TSASL 46*ebfedea0SLionel Sambuc #include <tsasl.h> 47*ebfedea0SLionel Sambuc #endif 48*ebfedea0SLionel Sambuc #include <krb5/resolve.h> 49*ebfedea0SLionel Sambuc #include <krb5/base64.h> 50*ebfedea0SLionel Sambuc #endif 51*ebfedea0SLionel Sambuc 52*ebfedea0SLionel Sambuc __RCSID("$NetBSD: ad.c,v 1.1.1.1 2011/04/13 18:15:29 elric Exp $"); 53*ebfedea0SLionel Sambuc 54*ebfedea0SLionel Sambuc #ifdef OPENLDAP 55*ebfedea0SLionel Sambuc 56*ebfedea0SLionel Sambuc #define CTX2LP(context) ((LDAP *)((context)->ldap_conn)) 57*ebfedea0SLionel Sambuc #define CTX2BASE(context) ((context)->base_dn) 58*ebfedea0SLionel Sambuc 59*ebfedea0SLionel Sambuc /* 60*ebfedea0SLionel Sambuc * userAccountControl 61*ebfedea0SLionel Sambuc */ 62*ebfedea0SLionel Sambuc 63*ebfedea0SLionel Sambuc #define UF_SCRIPT 0x00000001 64*ebfedea0SLionel Sambuc #define UF_ACCOUNTDISABLE 0x00000002 65*ebfedea0SLionel Sambuc #define UF_UNUSED_0 0x00000004 66*ebfedea0SLionel Sambuc #define UF_HOMEDIR_REQUIRED 0x00000008 67*ebfedea0SLionel Sambuc #define UF_LOCKOUT 0x00000010 68*ebfedea0SLionel Sambuc #define UF_PASSWD_NOTREQD 0x00000020 69*ebfedea0SLionel Sambuc #define UF_PASSWD_CANT_CHANGE 0x00000040 70*ebfedea0SLionel Sambuc #define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 71*ebfedea0SLionel Sambuc #define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 72*ebfedea0SLionel Sambuc #define UF_NORMAL_ACCOUNT 0x00000200 73*ebfedea0SLionel Sambuc #define UF_UNUSED_1 0x00000400 74*ebfedea0SLionel Sambuc #define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 75*ebfedea0SLionel Sambuc #define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 76*ebfedea0SLionel Sambuc #define UF_SERVER_TRUST_ACCOUNT 0x00002000 77*ebfedea0SLionel Sambuc #define UF_UNUSED_2 0x00004000 78*ebfedea0SLionel Sambuc #define UF_UNUSED_3 0x00008000 79*ebfedea0SLionel Sambuc #define UF_PASSWD_NOT_EXPIRE 0x00010000 80*ebfedea0SLionel Sambuc #define UF_MNS_LOGON_ACCOUNT 0x00020000 81*ebfedea0SLionel Sambuc #define UF_SMARTCARD_REQUIRED 0x00040000 82*ebfedea0SLionel Sambuc #define UF_TRUSTED_FOR_DELEGATION 0x00080000 83*ebfedea0SLionel Sambuc #define UF_NOT_DELEGATED 0x00100000 84*ebfedea0SLionel Sambuc #define UF_USE_DES_KEY_ONLY 0x00200000 85*ebfedea0SLionel Sambuc #define UF_DONT_REQUIRE_PREAUTH 0x00400000 86*ebfedea0SLionel Sambuc #define UF_UNUSED_4 0x00800000 87*ebfedea0SLionel Sambuc #define UF_UNUSED_5 0x01000000 88*ebfedea0SLionel Sambuc #define UF_UNUSED_6 0x02000000 89*ebfedea0SLionel Sambuc #define UF_UNUSED_7 0x04000000 90*ebfedea0SLionel Sambuc #define UF_UNUSED_8 0x08000000 91*ebfedea0SLionel Sambuc #define UF_UNUSED_9 0x10000000 92*ebfedea0SLionel Sambuc #define UF_UNUSED_10 0x20000000 93*ebfedea0SLionel Sambuc #define UF_UNUSED_11 0x40000000 94*ebfedea0SLionel Sambuc #define UF_UNUSED_12 0x80000000 95*ebfedea0SLionel Sambuc 96*ebfedea0SLionel Sambuc /* 97*ebfedea0SLionel Sambuc * 98*ebfedea0SLionel Sambuc */ 99*ebfedea0SLionel Sambuc 100*ebfedea0SLionel Sambuc #ifndef HAVE_TSASL 101*ebfedea0SLionel Sambuc static int 102*ebfedea0SLionel Sambuc sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *interact) 103*ebfedea0SLionel Sambuc { 104*ebfedea0SLionel Sambuc return LDAP_SUCCESS; 105*ebfedea0SLionel Sambuc } 106*ebfedea0SLionel Sambuc #endif 107*ebfedea0SLionel Sambuc 108*ebfedea0SLionel Sambuc #if 0 109*ebfedea0SLionel Sambuc static Sockbuf_IO ldap_tsasl_io = { 110*ebfedea0SLionel Sambuc NULL, /* sbi_setup */ 111*ebfedea0SLionel Sambuc NULL, /* sbi_remove */ 112*ebfedea0SLionel Sambuc NULL, /* sbi_ctrl */ 113*ebfedea0SLionel Sambuc NULL, /* sbi_read */ 114*ebfedea0SLionel Sambuc NULL, /* sbi_write */ 115*ebfedea0SLionel Sambuc NULL /* sbi_close */ 116*ebfedea0SLionel Sambuc }; 117*ebfedea0SLionel Sambuc #endif 118*ebfedea0SLionel Sambuc 119*ebfedea0SLionel Sambuc #ifdef HAVE_TSASL 120*ebfedea0SLionel Sambuc static int 121*ebfedea0SLionel Sambuc ldap_tsasl_bind_s(LDAP *ld, 122*ebfedea0SLionel Sambuc LDAP_CONST char *dn, 123*ebfedea0SLionel Sambuc LDAPControl **serverControls, 124*ebfedea0SLionel Sambuc LDAPControl **clientControls, 125*ebfedea0SLionel Sambuc const char *host) 126*ebfedea0SLionel Sambuc { 127*ebfedea0SLionel Sambuc char *attrs[] = { "supportedSASLMechanisms", NULL }; 128*ebfedea0SLionel Sambuc struct tsasl_peer *peer = NULL; 129*ebfedea0SLionel Sambuc struct tsasl_buffer in, out; 130*ebfedea0SLionel Sambuc struct berval ccred, *scred; 131*ebfedea0SLionel Sambuc LDAPMessage *m, *m0; 132*ebfedea0SLionel Sambuc const char *mech; 133*ebfedea0SLionel Sambuc char **vals; 134*ebfedea0SLionel Sambuc int ret, rc; 135*ebfedea0SLionel Sambuc 136*ebfedea0SLionel Sambuc ret = tsasl_peer_init(TSASL_FLAGS_INITIATOR | TSASL_FLAGS_CLEAR, 137*ebfedea0SLionel Sambuc "ldap", host, &peer); 138*ebfedea0SLionel Sambuc if (ret != TSASL_DONE) { 139*ebfedea0SLionel Sambuc rc = LDAP_LOCAL_ERROR; 140*ebfedea0SLionel Sambuc goto out; 141*ebfedea0SLionel Sambuc } 142*ebfedea0SLionel Sambuc 143*ebfedea0SLionel Sambuc rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE, NULL, attrs, 0, &m0); 144*ebfedea0SLionel Sambuc if (rc != LDAP_SUCCESS) 145*ebfedea0SLionel Sambuc goto out; 146*ebfedea0SLionel Sambuc 147*ebfedea0SLionel Sambuc m = ldap_first_entry(ld, m0); 148*ebfedea0SLionel Sambuc if (m == NULL) { 149*ebfedea0SLionel Sambuc ldap_msgfree(m0); 150*ebfedea0SLionel Sambuc goto out; 151*ebfedea0SLionel Sambuc } 152*ebfedea0SLionel Sambuc 153*ebfedea0SLionel Sambuc vals = ldap_get_values(ld, m, "supportedSASLMechanisms"); 154*ebfedea0SLionel Sambuc if (vals == NULL) { 155*ebfedea0SLionel Sambuc ldap_msgfree(m0); 156*ebfedea0SLionel Sambuc goto out; 157*ebfedea0SLionel Sambuc } 158*ebfedea0SLionel Sambuc 159*ebfedea0SLionel Sambuc ret = tsasl_find_best_mech(peer, vals, &mech); 160*ebfedea0SLionel Sambuc if (ret) { 161*ebfedea0SLionel Sambuc ldap_msgfree(m0); 162*ebfedea0SLionel Sambuc goto out; 163*ebfedea0SLionel Sambuc } 164*ebfedea0SLionel Sambuc 165*ebfedea0SLionel Sambuc ldap_msgfree(m0); 166*ebfedea0SLionel Sambuc 167*ebfedea0SLionel Sambuc ret = tsasl_select_mech(peer, mech); 168*ebfedea0SLionel Sambuc if (ret != TSASL_DONE) { 169*ebfedea0SLionel Sambuc rc = LDAP_LOCAL_ERROR; 170*ebfedea0SLionel Sambuc goto out; 171*ebfedea0SLionel Sambuc } 172*ebfedea0SLionel Sambuc 173*ebfedea0SLionel Sambuc in.tb_data = NULL; 174*ebfedea0SLionel Sambuc in.tb_size = 0; 175*ebfedea0SLionel Sambuc 176*ebfedea0SLionel Sambuc do { 177*ebfedea0SLionel Sambuc ret = tsasl_request(peer, &in, &out); 178*ebfedea0SLionel Sambuc if (in.tb_size != 0) { 179*ebfedea0SLionel Sambuc free(in.tb_data); 180*ebfedea0SLionel Sambuc in.tb_data = NULL; 181*ebfedea0SLionel Sambuc in.tb_size = 0; 182*ebfedea0SLionel Sambuc } 183*ebfedea0SLionel Sambuc if (ret != TSASL_DONE && ret != TSASL_CONTINUE) { 184*ebfedea0SLionel Sambuc rc = LDAP_AUTH_UNKNOWN; 185*ebfedea0SLionel Sambuc goto out; 186*ebfedea0SLionel Sambuc } 187*ebfedea0SLionel Sambuc 188*ebfedea0SLionel Sambuc ccred.bv_val = out.tb_data; 189*ebfedea0SLionel Sambuc ccred.bv_len = out.tb_size; 190*ebfedea0SLionel Sambuc 191*ebfedea0SLionel Sambuc rc = ldap_sasl_bind_s(ld, dn, mech, &ccred, 192*ebfedea0SLionel Sambuc serverControls, clientControls, &scred); 193*ebfedea0SLionel Sambuc tsasl_buffer_free(&out); 194*ebfedea0SLionel Sambuc 195*ebfedea0SLionel Sambuc if (rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS) { 196*ebfedea0SLionel Sambuc if(scred && scred->bv_len) 197*ebfedea0SLionel Sambuc ber_bvfree(scred); 198*ebfedea0SLionel Sambuc goto out; 199*ebfedea0SLionel Sambuc } 200*ebfedea0SLionel Sambuc 201*ebfedea0SLionel Sambuc in.tb_data = malloc(scred->bv_len); 202*ebfedea0SLionel Sambuc if (in.tb_data == NULL) { 203*ebfedea0SLionel Sambuc rc = LDAP_LOCAL_ERROR; 204*ebfedea0SLionel Sambuc goto out; 205*ebfedea0SLionel Sambuc } 206*ebfedea0SLionel Sambuc memcpy(in.tb_data, scred->bv_val, scred->bv_len); 207*ebfedea0SLionel Sambuc in.tb_size = scred->bv_len; 208*ebfedea0SLionel Sambuc ber_bvfree(scred); 209*ebfedea0SLionel Sambuc 210*ebfedea0SLionel Sambuc } while (rc == LDAP_SASL_BIND_IN_PROGRESS); 211*ebfedea0SLionel Sambuc 212*ebfedea0SLionel Sambuc out: 213*ebfedea0SLionel Sambuc if (rc == LDAP_SUCCESS) { 214*ebfedea0SLionel Sambuc #if 0 215*ebfedea0SLionel Sambuc ber_sockbuf_add_io(ld->ld_conns->lconn_sb, &ldap_tsasl_io, 216*ebfedea0SLionel Sambuc LBER_SBIOD_LEVEL_APPLICATION, peer); 217*ebfedea0SLionel Sambuc 218*ebfedea0SLionel Sambuc #endif 219*ebfedea0SLionel Sambuc } else if (peer != NULL) 220*ebfedea0SLionel Sambuc tsasl_peer_free(peer); 221*ebfedea0SLionel Sambuc 222*ebfedea0SLionel Sambuc return rc; 223*ebfedea0SLionel Sambuc } 224*ebfedea0SLionel Sambuc #endif /* HAVE_TSASL */ 225*ebfedea0SLionel Sambuc 226*ebfedea0SLionel Sambuc 227*ebfedea0SLionel Sambuc static int 228*ebfedea0SLionel Sambuc check_ldap(kadm5_ad_context *context, int ret) 229*ebfedea0SLionel Sambuc { 230*ebfedea0SLionel Sambuc switch (ret) { 231*ebfedea0SLionel Sambuc case LDAP_SUCCESS: 232*ebfedea0SLionel Sambuc return 0; 233*ebfedea0SLionel Sambuc case LDAP_SERVER_DOWN: { 234*ebfedea0SLionel Sambuc LDAP *lp = CTX2LP(context); 235*ebfedea0SLionel Sambuc ldap_unbind(lp); 236*ebfedea0SLionel Sambuc context->ldap_conn = NULL; 237*ebfedea0SLionel Sambuc free(context->base_dn); 238*ebfedea0SLionel Sambuc context->base_dn = NULL; 239*ebfedea0SLionel Sambuc return 1; 240*ebfedea0SLionel Sambuc } 241*ebfedea0SLionel Sambuc default: 242*ebfedea0SLionel Sambuc return 1; 243*ebfedea0SLionel Sambuc } 244*ebfedea0SLionel Sambuc } 245*ebfedea0SLionel Sambuc 246*ebfedea0SLionel Sambuc /* 247*ebfedea0SLionel Sambuc * 248*ebfedea0SLionel Sambuc */ 249*ebfedea0SLionel Sambuc 250*ebfedea0SLionel Sambuc static void 251*ebfedea0SLionel Sambuc laddattr(char ***al, int *attrlen, char *attr) 252*ebfedea0SLionel Sambuc { 253*ebfedea0SLionel Sambuc char **a; 254*ebfedea0SLionel Sambuc a = realloc(*al, (*attrlen + 2) * sizeof(**al)); 255*ebfedea0SLionel Sambuc if (a == NULL) 256*ebfedea0SLionel Sambuc return; 257*ebfedea0SLionel Sambuc a[*attrlen] = attr; 258*ebfedea0SLionel Sambuc a[*attrlen + 1] = NULL; 259*ebfedea0SLionel Sambuc (*attrlen)++; 260*ebfedea0SLionel Sambuc *al = a; 261*ebfedea0SLionel Sambuc } 262*ebfedea0SLionel Sambuc 263*ebfedea0SLionel Sambuc static kadm5_ret_t 264*ebfedea0SLionel Sambuc _kadm5_ad_connect(void *server_handle) 265*ebfedea0SLionel Sambuc { 266*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 267*ebfedea0SLionel Sambuc struct { 268*ebfedea0SLionel Sambuc char *server; 269*ebfedea0SLionel Sambuc int port; 270*ebfedea0SLionel Sambuc } *s, *servers = NULL; 271*ebfedea0SLionel Sambuc int i, num_servers = 0; 272*ebfedea0SLionel Sambuc 273*ebfedea0SLionel Sambuc if (context->ldap_conn) 274*ebfedea0SLionel Sambuc return 0; 275*ebfedea0SLionel Sambuc 276*ebfedea0SLionel Sambuc { 277*ebfedea0SLionel Sambuc struct dns_reply *r; 278*ebfedea0SLionel Sambuc struct resource_record *rr; 279*ebfedea0SLionel Sambuc char *domain; 280*ebfedea0SLionel Sambuc 281*ebfedea0SLionel Sambuc asprintf(&domain, "_ldap._tcp.%s", context->realm); 282*ebfedea0SLionel Sambuc if (domain == NULL) { 283*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_NO_SRV, "malloc"); 284*ebfedea0SLionel Sambuc return KADM5_NO_SRV; 285*ebfedea0SLionel Sambuc } 286*ebfedea0SLionel Sambuc 287*ebfedea0SLionel Sambuc r = dns_lookup(domain, "SRV"); 288*ebfedea0SLionel Sambuc free(domain); 289*ebfedea0SLionel Sambuc if (r == NULL) { 290*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_NO_SRV, "Didn't find ldap dns"); 291*ebfedea0SLionel Sambuc return KADM5_NO_SRV; 292*ebfedea0SLionel Sambuc } 293*ebfedea0SLionel Sambuc 294*ebfedea0SLionel Sambuc for (rr = r->head ; rr != NULL; rr = rr->next) { 295*ebfedea0SLionel Sambuc if (rr->type != rk_ns_t_srv) 296*ebfedea0SLionel Sambuc continue; 297*ebfedea0SLionel Sambuc s = realloc(servers, sizeof(*servers) * (num_servers + 1)); 298*ebfedea0SLionel Sambuc if (s == NULL) { 299*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "malloc"); 300*ebfedea0SLionel Sambuc dns_free_data(r); 301*ebfedea0SLionel Sambuc goto fail; 302*ebfedea0SLionel Sambuc } 303*ebfedea0SLionel Sambuc servers = s; 304*ebfedea0SLionel Sambuc num_servers++; 305*ebfedea0SLionel Sambuc servers[num_servers - 1].port = rr->u.srv->port; 306*ebfedea0SLionel Sambuc servers[num_servers - 1].server = strdup(rr->u.srv->target); 307*ebfedea0SLionel Sambuc } 308*ebfedea0SLionel Sambuc dns_free_data(r); 309*ebfedea0SLionel Sambuc } 310*ebfedea0SLionel Sambuc 311*ebfedea0SLionel Sambuc if (num_servers == 0) { 312*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_NO_SRV, "No AD server found in DNS"); 313*ebfedea0SLionel Sambuc return KADM5_NO_SRV; 314*ebfedea0SLionel Sambuc } 315*ebfedea0SLionel Sambuc 316*ebfedea0SLionel Sambuc for (i = 0; i < num_servers; i++) { 317*ebfedea0SLionel Sambuc int lret, version = LDAP_VERSION3; 318*ebfedea0SLionel Sambuc LDAP *lp; 319*ebfedea0SLionel Sambuc 320*ebfedea0SLionel Sambuc lp = ldap_init(servers[i].server, servers[i].port); 321*ebfedea0SLionel Sambuc if (lp == NULL) 322*ebfedea0SLionel Sambuc continue; 323*ebfedea0SLionel Sambuc 324*ebfedea0SLionel Sambuc if (ldap_set_option(lp, LDAP_OPT_PROTOCOL_VERSION, &version)) { 325*ebfedea0SLionel Sambuc ldap_unbind(lp); 326*ebfedea0SLionel Sambuc continue; 327*ebfedea0SLionel Sambuc } 328*ebfedea0SLionel Sambuc 329*ebfedea0SLionel Sambuc if (ldap_set_option(lp, LDAP_OPT_REFERRALS, LDAP_OPT_OFF)) { 330*ebfedea0SLionel Sambuc ldap_unbind(lp); 331*ebfedea0SLionel Sambuc continue; 332*ebfedea0SLionel Sambuc } 333*ebfedea0SLionel Sambuc 334*ebfedea0SLionel Sambuc #ifdef HAVE_TSASL 335*ebfedea0SLionel Sambuc lret = ldap_tsasl_bind_s(lp, NULL, NULL, NULL, servers[i].server); 336*ebfedea0SLionel Sambuc 337*ebfedea0SLionel Sambuc #else 338*ebfedea0SLionel Sambuc lret = ldap_sasl_interactive_bind_s(lp, NULL, NULL, NULL, NULL, 339*ebfedea0SLionel Sambuc LDAP_SASL_QUIET, 340*ebfedea0SLionel Sambuc sasl_interact, NULL); 341*ebfedea0SLionel Sambuc #endif 342*ebfedea0SLionel Sambuc if (lret != LDAP_SUCCESS) { 343*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, 0, 344*ebfedea0SLionel Sambuc "Couldn't contact any AD servers: %s", 345*ebfedea0SLionel Sambuc ldap_err2string(lret)); 346*ebfedea0SLionel Sambuc ldap_unbind(lp); 347*ebfedea0SLionel Sambuc continue; 348*ebfedea0SLionel Sambuc } 349*ebfedea0SLionel Sambuc 350*ebfedea0SLionel Sambuc context->ldap_conn = lp; 351*ebfedea0SLionel Sambuc break; 352*ebfedea0SLionel Sambuc } 353*ebfedea0SLionel Sambuc if (i >= num_servers) { 354*ebfedea0SLionel Sambuc goto fail; 355*ebfedea0SLionel Sambuc } 356*ebfedea0SLionel Sambuc 357*ebfedea0SLionel Sambuc { 358*ebfedea0SLionel Sambuc LDAPMessage *m, *m0; 359*ebfedea0SLionel Sambuc char **attr = NULL; 360*ebfedea0SLionel Sambuc int attrlen = 0; 361*ebfedea0SLionel Sambuc char **vals; 362*ebfedea0SLionel Sambuc int ret; 363*ebfedea0SLionel Sambuc 364*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "defaultNamingContext"); 365*ebfedea0SLionel Sambuc 366*ebfedea0SLionel Sambuc ret = ldap_search_s(CTX2LP(context), "", LDAP_SCOPE_BASE, 367*ebfedea0SLionel Sambuc "objectclass=*", attr, 0, &m); 368*ebfedea0SLionel Sambuc free(attr); 369*ebfedea0SLionel Sambuc if (check_ldap(context, ret)) 370*ebfedea0SLionel Sambuc goto fail; 371*ebfedea0SLionel Sambuc 372*ebfedea0SLionel Sambuc if (ldap_count_entries(CTX2LP(context), m) > 0) { 373*ebfedea0SLionel Sambuc m0 = ldap_first_entry(CTX2LP(context), m); 374*ebfedea0SLionel Sambuc if (m0 == NULL) { 375*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, 376*ebfedea0SLionel Sambuc "Error in AD ldap responce"); 377*ebfedea0SLionel Sambuc ldap_msgfree(m); 378*ebfedea0SLionel Sambuc goto fail; 379*ebfedea0SLionel Sambuc } 380*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), 381*ebfedea0SLionel Sambuc m0, "defaultNamingContext"); 382*ebfedea0SLionel Sambuc if (vals == NULL) { 383*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, 384*ebfedea0SLionel Sambuc "No naming context found"); 385*ebfedea0SLionel Sambuc goto fail; 386*ebfedea0SLionel Sambuc } 387*ebfedea0SLionel Sambuc context->base_dn = strdup(vals[0]); 388*ebfedea0SLionel Sambuc } else 389*ebfedea0SLionel Sambuc goto fail; 390*ebfedea0SLionel Sambuc ldap_msgfree(m); 391*ebfedea0SLionel Sambuc } 392*ebfedea0SLionel Sambuc 393*ebfedea0SLionel Sambuc for (i = 0; i < num_servers; i++) 394*ebfedea0SLionel Sambuc free(servers[i].server); 395*ebfedea0SLionel Sambuc free(servers); 396*ebfedea0SLionel Sambuc 397*ebfedea0SLionel Sambuc return 0; 398*ebfedea0SLionel Sambuc 399*ebfedea0SLionel Sambuc fail: 400*ebfedea0SLionel Sambuc for (i = 0; i < num_servers; i++) 401*ebfedea0SLionel Sambuc free(servers[i].server); 402*ebfedea0SLionel Sambuc free(servers); 403*ebfedea0SLionel Sambuc 404*ebfedea0SLionel Sambuc if (context->ldap_conn) { 405*ebfedea0SLionel Sambuc ldap_unbind(CTX2LP(context)); 406*ebfedea0SLionel Sambuc context->ldap_conn = NULL; 407*ebfedea0SLionel Sambuc } 408*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 409*ebfedea0SLionel Sambuc } 410*ebfedea0SLionel Sambuc 411*ebfedea0SLionel Sambuc #define NTTIME_EPOCH 0x019DB1DED53E8000LL 412*ebfedea0SLionel Sambuc 413*ebfedea0SLionel Sambuc static time_t 414*ebfedea0SLionel Sambuc nt2unixtime(const char *str) 415*ebfedea0SLionel Sambuc { 416*ebfedea0SLionel Sambuc unsigned long long t; 417*ebfedea0SLionel Sambuc t = strtoll(str, NULL, 10); 418*ebfedea0SLionel Sambuc t = ((t - NTTIME_EPOCH) / (long long)10000000); 419*ebfedea0SLionel Sambuc if (t > (((time_t)(~(long long)0)) >> 1)) 420*ebfedea0SLionel Sambuc return 0; 421*ebfedea0SLionel Sambuc return (time_t)t; 422*ebfedea0SLionel Sambuc } 423*ebfedea0SLionel Sambuc 424*ebfedea0SLionel Sambuc static long long 425*ebfedea0SLionel Sambuc unix2nttime(time_t unix_time) 426*ebfedea0SLionel Sambuc { 427*ebfedea0SLionel Sambuc long long wt; 428*ebfedea0SLionel Sambuc wt = unix_time * (long long)10000000 + (long long)NTTIME_EPOCH; 429*ebfedea0SLionel Sambuc return wt; 430*ebfedea0SLionel Sambuc } 431*ebfedea0SLionel Sambuc 432*ebfedea0SLionel Sambuc /* XXX create filter in a better way */ 433*ebfedea0SLionel Sambuc 434*ebfedea0SLionel Sambuc static int 435*ebfedea0SLionel Sambuc ad_find_entry(kadm5_ad_context *context, 436*ebfedea0SLionel Sambuc const char *fqdn, 437*ebfedea0SLionel Sambuc const char *pn, 438*ebfedea0SLionel Sambuc char **name) 439*ebfedea0SLionel Sambuc { 440*ebfedea0SLionel Sambuc LDAPMessage *m, *m0; 441*ebfedea0SLionel Sambuc char *attr[] = { "distinguishedName", NULL }; 442*ebfedea0SLionel Sambuc char *filter; 443*ebfedea0SLionel Sambuc int ret; 444*ebfedea0SLionel Sambuc 445*ebfedea0SLionel Sambuc if (name) 446*ebfedea0SLionel Sambuc *name = NULL; 447*ebfedea0SLionel Sambuc 448*ebfedea0SLionel Sambuc if (fqdn) 449*ebfedea0SLionel Sambuc asprintf(&filter, 450*ebfedea0SLionel Sambuc "(&(objectClass=computer)(|(dNSHostName=%s)(servicePrincipalName=%s)))", 451*ebfedea0SLionel Sambuc fqdn, pn); 452*ebfedea0SLionel Sambuc else if(pn) 453*ebfedea0SLionel Sambuc asprintf(&filter, "(&(objectClass=account)(userPrincipalName=%s))", pn); 454*ebfedea0SLionel Sambuc else 455*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 456*ebfedea0SLionel Sambuc 457*ebfedea0SLionel Sambuc ret = ldap_search_s(CTX2LP(context), CTX2BASE(context), 458*ebfedea0SLionel Sambuc LDAP_SCOPE_SUBTREE, 459*ebfedea0SLionel Sambuc filter, attr, 0, &m); 460*ebfedea0SLionel Sambuc free(filter); 461*ebfedea0SLionel Sambuc if (check_ldap(context, ret)) 462*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 463*ebfedea0SLionel Sambuc 464*ebfedea0SLionel Sambuc if (ldap_count_entries(CTX2LP(context), m) > 0) { 465*ebfedea0SLionel Sambuc char **vals; 466*ebfedea0SLionel Sambuc m0 = ldap_first_entry(CTX2LP(context), m); 467*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "distinguishedName"); 468*ebfedea0SLionel Sambuc if (vals == NULL || vals[0] == NULL) { 469*ebfedea0SLionel Sambuc ldap_msgfree(m); 470*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 471*ebfedea0SLionel Sambuc } 472*ebfedea0SLionel Sambuc if (name) 473*ebfedea0SLionel Sambuc *name = strdup(vals[0]); 474*ebfedea0SLionel Sambuc ldap_msgfree(m); 475*ebfedea0SLionel Sambuc } else 476*ebfedea0SLionel Sambuc return KADM5_UNK_PRINC; 477*ebfedea0SLionel Sambuc 478*ebfedea0SLionel Sambuc return 0; 479*ebfedea0SLionel Sambuc } 480*ebfedea0SLionel Sambuc 481*ebfedea0SLionel Sambuc #endif /* OPENLDAP */ 482*ebfedea0SLionel Sambuc 483*ebfedea0SLionel Sambuc static kadm5_ret_t 484*ebfedea0SLionel Sambuc ad_get_cred(kadm5_ad_context *context, const char *password) 485*ebfedea0SLionel Sambuc { 486*ebfedea0SLionel Sambuc kadm5_ret_t ret; 487*ebfedea0SLionel Sambuc krb5_ccache cc; 488*ebfedea0SLionel Sambuc char *service; 489*ebfedea0SLionel Sambuc 490*ebfedea0SLionel Sambuc if (context->ccache) 491*ebfedea0SLionel Sambuc return 0; 492*ebfedea0SLionel Sambuc 493*ebfedea0SLionel Sambuc asprintf(&service, "%s/%s@%s", KRB5_TGS_NAME, 494*ebfedea0SLionel Sambuc context->realm, context->realm); 495*ebfedea0SLionel Sambuc if (service == NULL) 496*ebfedea0SLionel Sambuc return ENOMEM; 497*ebfedea0SLionel Sambuc 498*ebfedea0SLionel Sambuc ret = _kadm5_c_get_cred_cache(context->context, 499*ebfedea0SLionel Sambuc context->client_name, 500*ebfedea0SLionel Sambuc service, 501*ebfedea0SLionel Sambuc password, krb5_prompter_posix, 502*ebfedea0SLionel Sambuc NULL, NULL, &cc); 503*ebfedea0SLionel Sambuc free(service); 504*ebfedea0SLionel Sambuc if(ret) 505*ebfedea0SLionel Sambuc return ret; /* XXX */ 506*ebfedea0SLionel Sambuc context->ccache = cc; 507*ebfedea0SLionel Sambuc return 0; 508*ebfedea0SLionel Sambuc } 509*ebfedea0SLionel Sambuc 510*ebfedea0SLionel Sambuc static kadm5_ret_t 511*ebfedea0SLionel Sambuc kadm5_ad_chpass_principal(void *server_handle, 512*ebfedea0SLionel Sambuc krb5_principal principal, 513*ebfedea0SLionel Sambuc const char *password) 514*ebfedea0SLionel Sambuc { 515*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 516*ebfedea0SLionel Sambuc krb5_data result_code_string, result_string; 517*ebfedea0SLionel Sambuc int result_code; 518*ebfedea0SLionel Sambuc kadm5_ret_t ret; 519*ebfedea0SLionel Sambuc 520*ebfedea0SLionel Sambuc ret = ad_get_cred(context, NULL); 521*ebfedea0SLionel Sambuc if (ret) 522*ebfedea0SLionel Sambuc return ret; 523*ebfedea0SLionel Sambuc 524*ebfedea0SLionel Sambuc krb5_data_zero (&result_code_string); 525*ebfedea0SLionel Sambuc krb5_data_zero (&result_string); 526*ebfedea0SLionel Sambuc 527*ebfedea0SLionel Sambuc ret = krb5_set_password_using_ccache (context->context, 528*ebfedea0SLionel Sambuc context->ccache, 529*ebfedea0SLionel Sambuc password, 530*ebfedea0SLionel Sambuc principal, 531*ebfedea0SLionel Sambuc &result_code, 532*ebfedea0SLionel Sambuc &result_code_string, 533*ebfedea0SLionel Sambuc &result_string); 534*ebfedea0SLionel Sambuc 535*ebfedea0SLionel Sambuc krb5_data_free (&result_code_string); 536*ebfedea0SLionel Sambuc krb5_data_free (&result_string); 537*ebfedea0SLionel Sambuc 538*ebfedea0SLionel Sambuc /* XXX do mapping here on error codes */ 539*ebfedea0SLionel Sambuc 540*ebfedea0SLionel Sambuc return ret; 541*ebfedea0SLionel Sambuc } 542*ebfedea0SLionel Sambuc 543*ebfedea0SLionel Sambuc #ifdef OPENLDAP 544*ebfedea0SLionel Sambuc static const char * 545*ebfedea0SLionel Sambuc get_fqdn(krb5_context context, const krb5_principal p) 546*ebfedea0SLionel Sambuc { 547*ebfedea0SLionel Sambuc const char *s, *hosttypes[] = { "host", "ldap", "gc", "cifs", "dns" }; 548*ebfedea0SLionel Sambuc int i; 549*ebfedea0SLionel Sambuc 550*ebfedea0SLionel Sambuc s = krb5_principal_get_comp_string(context, p, 0); 551*ebfedea0SLionel Sambuc if (p == NULL) 552*ebfedea0SLionel Sambuc return NULL; 553*ebfedea0SLionel Sambuc 554*ebfedea0SLionel Sambuc for (i = 0; i < sizeof(hosttypes)/sizeof(hosttypes[0]); i++) { 555*ebfedea0SLionel Sambuc if (strcasecmp(s, hosttypes[i]) == 0) 556*ebfedea0SLionel Sambuc return krb5_principal_get_comp_string(context, p, 1); 557*ebfedea0SLionel Sambuc } 558*ebfedea0SLionel Sambuc return 0; 559*ebfedea0SLionel Sambuc } 560*ebfedea0SLionel Sambuc #endif 561*ebfedea0SLionel Sambuc 562*ebfedea0SLionel Sambuc 563*ebfedea0SLionel Sambuc static kadm5_ret_t 564*ebfedea0SLionel Sambuc kadm5_ad_create_principal(void *server_handle, 565*ebfedea0SLionel Sambuc kadm5_principal_ent_t entry, 566*ebfedea0SLionel Sambuc uint32_t mask, 567*ebfedea0SLionel Sambuc const char *password) 568*ebfedea0SLionel Sambuc { 569*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 570*ebfedea0SLionel Sambuc 571*ebfedea0SLionel Sambuc /* 572*ebfedea0SLionel Sambuc * KADM5_PRINC_EXPIRE_TIME 573*ebfedea0SLionel Sambuc * 574*ebfedea0SLionel Sambuc * return 0 || KADM5_DUP; 575*ebfedea0SLionel Sambuc */ 576*ebfedea0SLionel Sambuc 577*ebfedea0SLionel Sambuc #ifdef OPENLDAP 578*ebfedea0SLionel Sambuc LDAPMod *attrs[8], rattrs[7], *a; 579*ebfedea0SLionel Sambuc char *useraccvals[2] = { NULL, NULL }, 580*ebfedea0SLionel Sambuc *samvals[2], *dnsvals[2], *spnvals[5], *upnvals[2], *tv[2]; 581*ebfedea0SLionel Sambuc char *ocvals_spn[] = { "top", "person", "organizationalPerson", 582*ebfedea0SLionel Sambuc "user", "computer", NULL}; 583*ebfedea0SLionel Sambuc char *p, *realmless_p, *p_msrealm = NULL, *dn = NULL; 584*ebfedea0SLionel Sambuc const char *fqdn; 585*ebfedea0SLionel Sambuc char *s, *samname = NULL, *short_spn = NULL; 586*ebfedea0SLionel Sambuc int ret, i; 587*ebfedea0SLionel Sambuc int32_t uf_flags = 0; 588*ebfedea0SLionel Sambuc 589*ebfedea0SLionel Sambuc if ((mask & KADM5_PRINCIPAL) == 0) 590*ebfedea0SLionel Sambuc return KADM5_BAD_MASK; 591*ebfedea0SLionel Sambuc 592*ebfedea0SLionel Sambuc for (i = 0; i < sizeof(rattrs)/sizeof(rattrs[0]); i++) 593*ebfedea0SLionel Sambuc attrs[i] = &rattrs[i]; 594*ebfedea0SLionel Sambuc attrs[i] = NULL; 595*ebfedea0SLionel Sambuc 596*ebfedea0SLionel Sambuc ret = ad_get_cred(context, NULL); 597*ebfedea0SLionel Sambuc if (ret) 598*ebfedea0SLionel Sambuc return ret; 599*ebfedea0SLionel Sambuc 600*ebfedea0SLionel Sambuc ret = _kadm5_ad_connect(server_handle); 601*ebfedea0SLionel Sambuc if (ret) 602*ebfedea0SLionel Sambuc return ret; 603*ebfedea0SLionel Sambuc 604*ebfedea0SLionel Sambuc fqdn = get_fqdn(context->context, entry->principal); 605*ebfedea0SLionel Sambuc 606*ebfedea0SLionel Sambuc ret = krb5_unparse_name(context->context, entry->principal, &p); 607*ebfedea0SLionel Sambuc if (ret) 608*ebfedea0SLionel Sambuc return ret; 609*ebfedea0SLionel Sambuc 610*ebfedea0SLionel Sambuc if (ad_find_entry(context, fqdn, p, NULL) == 0) { 611*ebfedea0SLionel Sambuc free(p); 612*ebfedea0SLionel Sambuc return KADM5_DUP; 613*ebfedea0SLionel Sambuc } 614*ebfedea0SLionel Sambuc 615*ebfedea0SLionel Sambuc if (mask & KADM5_ATTRIBUTES) { 616*ebfedea0SLionel Sambuc if (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX) 617*ebfedea0SLionel Sambuc uf_flags |= UF_ACCOUNTDISABLE|UF_LOCKOUT; 618*ebfedea0SLionel Sambuc if ((entry->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) == 0) 619*ebfedea0SLionel Sambuc uf_flags |= UF_DONT_REQUIRE_PREAUTH; 620*ebfedea0SLionel Sambuc if (entry->attributes & KRB5_KDB_REQUIRES_HW_AUTH) 621*ebfedea0SLionel Sambuc uf_flags |= UF_SMARTCARD_REQUIRED; 622*ebfedea0SLionel Sambuc } 623*ebfedea0SLionel Sambuc 624*ebfedea0SLionel Sambuc realmless_p = strdup(p); 625*ebfedea0SLionel Sambuc if (realmless_p == NULL) { 626*ebfedea0SLionel Sambuc ret = ENOMEM; 627*ebfedea0SLionel Sambuc goto out; 628*ebfedea0SLionel Sambuc } 629*ebfedea0SLionel Sambuc s = strrchr(realmless_p, '@'); 630*ebfedea0SLionel Sambuc if (s) 631*ebfedea0SLionel Sambuc *s = '\0'; 632*ebfedea0SLionel Sambuc 633*ebfedea0SLionel Sambuc if (fqdn) { 634*ebfedea0SLionel Sambuc /* create computer account */ 635*ebfedea0SLionel Sambuc asprintf(&samname, "%s$", fqdn); 636*ebfedea0SLionel Sambuc if (samname == NULL) { 637*ebfedea0SLionel Sambuc ret = ENOMEM; 638*ebfedea0SLionel Sambuc goto out; 639*ebfedea0SLionel Sambuc } 640*ebfedea0SLionel Sambuc s = strchr(samname, '.'); 641*ebfedea0SLionel Sambuc if (s) { 642*ebfedea0SLionel Sambuc s[0] = '$'; 643*ebfedea0SLionel Sambuc s[1] = '\0'; 644*ebfedea0SLionel Sambuc } 645*ebfedea0SLionel Sambuc 646*ebfedea0SLionel Sambuc short_spn = strdup(p); 647*ebfedea0SLionel Sambuc if (short_spn == NULL) { 648*ebfedea0SLionel Sambuc errno = ENOMEM; 649*ebfedea0SLionel Sambuc goto out; 650*ebfedea0SLionel Sambuc } 651*ebfedea0SLionel Sambuc s = strchr(short_spn, '.'); 652*ebfedea0SLionel Sambuc if (s) { 653*ebfedea0SLionel Sambuc *s = '\0'; 654*ebfedea0SLionel Sambuc } else { 655*ebfedea0SLionel Sambuc free(short_spn); 656*ebfedea0SLionel Sambuc short_spn = NULL; 657*ebfedea0SLionel Sambuc } 658*ebfedea0SLionel Sambuc 659*ebfedea0SLionel Sambuc p_msrealm = strdup(p); 660*ebfedea0SLionel Sambuc if (p_msrealm == NULL) { 661*ebfedea0SLionel Sambuc errno = ENOMEM; 662*ebfedea0SLionel Sambuc goto out; 663*ebfedea0SLionel Sambuc } 664*ebfedea0SLionel Sambuc s = strrchr(p_msrealm, '@'); 665*ebfedea0SLionel Sambuc if (s) { 666*ebfedea0SLionel Sambuc *s = '/'; 667*ebfedea0SLionel Sambuc } else { 668*ebfedea0SLionel Sambuc free(p_msrealm); 669*ebfedea0SLionel Sambuc p_msrealm = NULL; 670*ebfedea0SLionel Sambuc } 671*ebfedea0SLionel Sambuc 672*ebfedea0SLionel Sambuc asprintf(&dn, "cn=%s, cn=Computers, %s", fqdn, CTX2BASE(context)); 673*ebfedea0SLionel Sambuc if (dn == NULL) { 674*ebfedea0SLionel Sambuc ret = ENOMEM; 675*ebfedea0SLionel Sambuc goto out; 676*ebfedea0SLionel Sambuc } 677*ebfedea0SLionel Sambuc 678*ebfedea0SLionel Sambuc a = &rattrs[0]; 679*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 680*ebfedea0SLionel Sambuc a->mod_type = "objectClass"; 681*ebfedea0SLionel Sambuc a->mod_values = ocvals_spn; 682*ebfedea0SLionel Sambuc a++; 683*ebfedea0SLionel Sambuc 684*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 685*ebfedea0SLionel Sambuc a->mod_type = "userAccountControl"; 686*ebfedea0SLionel Sambuc a->mod_values = useraccvals; 687*ebfedea0SLionel Sambuc asprintf(&useraccvals[0], "%d", 688*ebfedea0SLionel Sambuc uf_flags | 689*ebfedea0SLionel Sambuc UF_PASSWD_NOT_EXPIRE | 690*ebfedea0SLionel Sambuc UF_WORKSTATION_TRUST_ACCOUNT); 691*ebfedea0SLionel Sambuc useraccvals[1] = NULL; 692*ebfedea0SLionel Sambuc a++; 693*ebfedea0SLionel Sambuc 694*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 695*ebfedea0SLionel Sambuc a->mod_type = "sAMAccountName"; 696*ebfedea0SLionel Sambuc a->mod_values = samvals; 697*ebfedea0SLionel Sambuc samvals[0] = samname; 698*ebfedea0SLionel Sambuc samvals[1] = NULL; 699*ebfedea0SLionel Sambuc a++; 700*ebfedea0SLionel Sambuc 701*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 702*ebfedea0SLionel Sambuc a->mod_type = "dNSHostName"; 703*ebfedea0SLionel Sambuc a->mod_values = dnsvals; 704*ebfedea0SLionel Sambuc dnsvals[0] = (char *)fqdn; 705*ebfedea0SLionel Sambuc dnsvals[1] = NULL; 706*ebfedea0SLionel Sambuc a++; 707*ebfedea0SLionel Sambuc 708*ebfedea0SLionel Sambuc /* XXX add even more spn's */ 709*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 710*ebfedea0SLionel Sambuc a->mod_type = "servicePrincipalName"; 711*ebfedea0SLionel Sambuc a->mod_values = spnvals; 712*ebfedea0SLionel Sambuc i = 0; 713*ebfedea0SLionel Sambuc spnvals[i++] = p; 714*ebfedea0SLionel Sambuc spnvals[i++] = realmless_p; 715*ebfedea0SLionel Sambuc if (short_spn) 716*ebfedea0SLionel Sambuc spnvals[i++] = short_spn; 717*ebfedea0SLionel Sambuc if (p_msrealm) 718*ebfedea0SLionel Sambuc spnvals[i++] = p_msrealm; 719*ebfedea0SLionel Sambuc spnvals[i++] = NULL; 720*ebfedea0SLionel Sambuc a++; 721*ebfedea0SLionel Sambuc 722*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 723*ebfedea0SLionel Sambuc a->mod_type = "userPrincipalName"; 724*ebfedea0SLionel Sambuc a->mod_values = upnvals; 725*ebfedea0SLionel Sambuc upnvals[0] = p; 726*ebfedea0SLionel Sambuc upnvals[1] = NULL; 727*ebfedea0SLionel Sambuc a++; 728*ebfedea0SLionel Sambuc 729*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 730*ebfedea0SLionel Sambuc a->mod_type = "accountExpires"; 731*ebfedea0SLionel Sambuc a->mod_values = tv; 732*ebfedea0SLionel Sambuc tv[0] = "9223372036854775807"; /* "never" */ 733*ebfedea0SLionel Sambuc tv[1] = NULL; 734*ebfedea0SLionel Sambuc a++; 735*ebfedea0SLionel Sambuc 736*ebfedea0SLionel Sambuc } else { 737*ebfedea0SLionel Sambuc /* create user account */ 738*ebfedea0SLionel Sambuc 739*ebfedea0SLionel Sambuc a = &rattrs[0]; 740*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 741*ebfedea0SLionel Sambuc a->mod_type = "userAccountControl"; 742*ebfedea0SLionel Sambuc a->mod_values = useraccvals; 743*ebfedea0SLionel Sambuc asprintf(&useraccvals[0], "%d", 744*ebfedea0SLionel Sambuc uf_flags | 745*ebfedea0SLionel Sambuc UF_PASSWD_NOT_EXPIRE); 746*ebfedea0SLionel Sambuc useraccvals[1] = NULL; 747*ebfedea0SLionel Sambuc a++; 748*ebfedea0SLionel Sambuc 749*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 750*ebfedea0SLionel Sambuc a->mod_type = "sAMAccountName"; 751*ebfedea0SLionel Sambuc a->mod_values = samvals; 752*ebfedea0SLionel Sambuc samvals[0] = realmless_p; 753*ebfedea0SLionel Sambuc samvals[1] = NULL; 754*ebfedea0SLionel Sambuc a++; 755*ebfedea0SLionel Sambuc 756*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 757*ebfedea0SLionel Sambuc a->mod_type = "userPrincipalName"; 758*ebfedea0SLionel Sambuc a->mod_values = upnvals; 759*ebfedea0SLionel Sambuc upnvals[0] = p; 760*ebfedea0SLionel Sambuc upnvals[1] = NULL; 761*ebfedea0SLionel Sambuc a++; 762*ebfedea0SLionel Sambuc 763*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_ADD; 764*ebfedea0SLionel Sambuc a->mod_type = "accountExpires"; 765*ebfedea0SLionel Sambuc a->mod_values = tv; 766*ebfedea0SLionel Sambuc tv[0] = "9223372036854775807"; /* "never" */ 767*ebfedea0SLionel Sambuc tv[1] = NULL; 768*ebfedea0SLionel Sambuc a++; 769*ebfedea0SLionel Sambuc } 770*ebfedea0SLionel Sambuc 771*ebfedea0SLionel Sambuc attrs[a - &rattrs[0]] = NULL; 772*ebfedea0SLionel Sambuc 773*ebfedea0SLionel Sambuc ret = ldap_add_s(CTX2LP(context), dn, attrs); 774*ebfedea0SLionel Sambuc 775*ebfedea0SLionel Sambuc out: 776*ebfedea0SLionel Sambuc if (useraccvals[0]) 777*ebfedea0SLionel Sambuc free(useraccvals[0]); 778*ebfedea0SLionel Sambuc if (realmless_p) 779*ebfedea0SLionel Sambuc free(realmless_p); 780*ebfedea0SLionel Sambuc if (samname) 781*ebfedea0SLionel Sambuc free(samname); 782*ebfedea0SLionel Sambuc if (short_spn) 783*ebfedea0SLionel Sambuc free(short_spn); 784*ebfedea0SLionel Sambuc if (p_msrealm) 785*ebfedea0SLionel Sambuc free(p_msrealm); 786*ebfedea0SLionel Sambuc free(p); 787*ebfedea0SLionel Sambuc 788*ebfedea0SLionel Sambuc if (check_ldap(context, ret)) 789*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 790*ebfedea0SLionel Sambuc 791*ebfedea0SLionel Sambuc return 0; 792*ebfedea0SLionel Sambuc #else 793*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 794*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 795*ebfedea0SLionel Sambuc #endif 796*ebfedea0SLionel Sambuc } 797*ebfedea0SLionel Sambuc 798*ebfedea0SLionel Sambuc static kadm5_ret_t 799*ebfedea0SLionel Sambuc kadm5_ad_delete_principal(void *server_handle, krb5_principal principal) 800*ebfedea0SLionel Sambuc { 801*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 802*ebfedea0SLionel Sambuc #ifdef OPENLDAP 803*ebfedea0SLionel Sambuc char *p, *dn = NULL; 804*ebfedea0SLionel Sambuc const char *fqdn; 805*ebfedea0SLionel Sambuc int ret; 806*ebfedea0SLionel Sambuc 807*ebfedea0SLionel Sambuc ret = ad_get_cred(context, NULL); 808*ebfedea0SLionel Sambuc if (ret) 809*ebfedea0SLionel Sambuc return ret; 810*ebfedea0SLionel Sambuc 811*ebfedea0SLionel Sambuc ret = _kadm5_ad_connect(server_handle); 812*ebfedea0SLionel Sambuc if (ret) 813*ebfedea0SLionel Sambuc return ret; 814*ebfedea0SLionel Sambuc 815*ebfedea0SLionel Sambuc fqdn = get_fqdn(context->context, principal); 816*ebfedea0SLionel Sambuc 817*ebfedea0SLionel Sambuc ret = krb5_unparse_name(context->context, principal, &p); 818*ebfedea0SLionel Sambuc if (ret) 819*ebfedea0SLionel Sambuc return ret; 820*ebfedea0SLionel Sambuc 821*ebfedea0SLionel Sambuc if (ad_find_entry(context, fqdn, p, &dn) != 0) { 822*ebfedea0SLionel Sambuc free(p); 823*ebfedea0SLionel Sambuc return KADM5_UNK_PRINC; 824*ebfedea0SLionel Sambuc } 825*ebfedea0SLionel Sambuc 826*ebfedea0SLionel Sambuc ret = ldap_delete_s(CTX2LP(context), dn); 827*ebfedea0SLionel Sambuc 828*ebfedea0SLionel Sambuc free(dn); 829*ebfedea0SLionel Sambuc free(p); 830*ebfedea0SLionel Sambuc 831*ebfedea0SLionel Sambuc if (check_ldap(context, ret)) 832*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 833*ebfedea0SLionel Sambuc return 0; 834*ebfedea0SLionel Sambuc #else 835*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 836*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 837*ebfedea0SLionel Sambuc #endif 838*ebfedea0SLionel Sambuc } 839*ebfedea0SLionel Sambuc 840*ebfedea0SLionel Sambuc static kadm5_ret_t 841*ebfedea0SLionel Sambuc kadm5_ad_destroy(void *server_handle) 842*ebfedea0SLionel Sambuc { 843*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 844*ebfedea0SLionel Sambuc 845*ebfedea0SLionel Sambuc if (context->ccache) 846*ebfedea0SLionel Sambuc krb5_cc_destroy(context->context, context->ccache); 847*ebfedea0SLionel Sambuc 848*ebfedea0SLionel Sambuc #ifdef OPENLDAP 849*ebfedea0SLionel Sambuc { 850*ebfedea0SLionel Sambuc LDAP *lp = CTX2LP(context); 851*ebfedea0SLionel Sambuc if (lp) 852*ebfedea0SLionel Sambuc ldap_unbind(lp); 853*ebfedea0SLionel Sambuc if (context->base_dn) 854*ebfedea0SLionel Sambuc free(context->base_dn); 855*ebfedea0SLionel Sambuc } 856*ebfedea0SLionel Sambuc #endif 857*ebfedea0SLionel Sambuc free(context->realm); 858*ebfedea0SLionel Sambuc free(context->client_name); 859*ebfedea0SLionel Sambuc krb5_free_principal(context->context, context->caller); 860*ebfedea0SLionel Sambuc if(context->my_context) 861*ebfedea0SLionel Sambuc krb5_free_context(context->context); 862*ebfedea0SLionel Sambuc return 0; 863*ebfedea0SLionel Sambuc } 864*ebfedea0SLionel Sambuc 865*ebfedea0SLionel Sambuc static kadm5_ret_t 866*ebfedea0SLionel Sambuc kadm5_ad_flush(void *server_handle) 867*ebfedea0SLionel Sambuc { 868*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 869*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 870*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 871*ebfedea0SLionel Sambuc } 872*ebfedea0SLionel Sambuc 873*ebfedea0SLionel Sambuc static kadm5_ret_t 874*ebfedea0SLionel Sambuc kadm5_ad_get_principal(void *server_handle, 875*ebfedea0SLionel Sambuc krb5_principal principal, 876*ebfedea0SLionel Sambuc kadm5_principal_ent_t entry, 877*ebfedea0SLionel Sambuc uint32_t mask) 878*ebfedea0SLionel Sambuc { 879*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 880*ebfedea0SLionel Sambuc #ifdef OPENLDAP 881*ebfedea0SLionel Sambuc LDAPMessage *m, *m0; 882*ebfedea0SLionel Sambuc char **attr = NULL; 883*ebfedea0SLionel Sambuc int attrlen = 0; 884*ebfedea0SLionel Sambuc char *filter, *p, *q, *u; 885*ebfedea0SLionel Sambuc int ret; 886*ebfedea0SLionel Sambuc 887*ebfedea0SLionel Sambuc /* 888*ebfedea0SLionel Sambuc * principal 889*ebfedea0SLionel Sambuc * KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES 890*ebfedea0SLionel Sambuc */ 891*ebfedea0SLionel Sambuc 892*ebfedea0SLionel Sambuc /* 893*ebfedea0SLionel Sambuc * return 0 || KADM5_DUP; 894*ebfedea0SLionel Sambuc */ 895*ebfedea0SLionel Sambuc 896*ebfedea0SLionel Sambuc memset(entry, 0, sizeof(*entry)); 897*ebfedea0SLionel Sambuc 898*ebfedea0SLionel Sambuc if (mask & KADM5_KVNO) 899*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "msDS-KeyVersionNumber"); 900*ebfedea0SLionel Sambuc 901*ebfedea0SLionel Sambuc if (mask & KADM5_PRINCIPAL) { 902*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "userPrincipalName"); 903*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "servicePrincipalName"); 904*ebfedea0SLionel Sambuc } 905*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "objectClass"); 906*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "lastLogon"); 907*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "badPwdCount"); 908*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "badPasswordTime"); 909*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "pwdLastSet"); 910*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "accountExpires"); 911*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "userAccountControl"); 912*ebfedea0SLionel Sambuc 913*ebfedea0SLionel Sambuc krb5_unparse_name_short(context->context, principal, &p); 914*ebfedea0SLionel Sambuc krb5_unparse_name(context->context, principal, &u); 915*ebfedea0SLionel Sambuc 916*ebfedea0SLionel Sambuc /* replace @ in domain part with a / */ 917*ebfedea0SLionel Sambuc q = strrchr(p, '@'); 918*ebfedea0SLionel Sambuc if (q && (p != q && *(q - 1) != '\\')) 919*ebfedea0SLionel Sambuc *q = '/'; 920*ebfedea0SLionel Sambuc 921*ebfedea0SLionel Sambuc asprintf(&filter, 922*ebfedea0SLionel Sambuc "(|(userPrincipalName=%s)(servicePrincipalName=%s)(servicePrincipalName=%s))", 923*ebfedea0SLionel Sambuc u, p, u); 924*ebfedea0SLionel Sambuc free(p); 925*ebfedea0SLionel Sambuc free(u); 926*ebfedea0SLionel Sambuc 927*ebfedea0SLionel Sambuc ret = ldap_search_s(CTX2LP(context), CTX2BASE(context), 928*ebfedea0SLionel Sambuc LDAP_SCOPE_SUBTREE, 929*ebfedea0SLionel Sambuc filter, attr, 0, &m); 930*ebfedea0SLionel Sambuc free(attr); 931*ebfedea0SLionel Sambuc if (check_ldap(context, ret)) 932*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 933*ebfedea0SLionel Sambuc 934*ebfedea0SLionel Sambuc if (ldap_count_entries(CTX2LP(context), m) > 0) { 935*ebfedea0SLionel Sambuc char **vals; 936*ebfedea0SLionel Sambuc m0 = ldap_first_entry(CTX2LP(context), m); 937*ebfedea0SLionel Sambuc if (m0 == NULL) { 938*ebfedea0SLionel Sambuc ldap_msgfree(m); 939*ebfedea0SLionel Sambuc goto fail; 940*ebfedea0SLionel Sambuc } 941*ebfedea0SLionel Sambuc #if 0 942*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "servicePrincipalName"); 943*ebfedea0SLionel Sambuc if (vals) 944*ebfedea0SLionel Sambuc printf("servicePrincipalName %s\n", vals[0]); 945*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "userPrincipalName"); 946*ebfedea0SLionel Sambuc if (vals) 947*ebfedea0SLionel Sambuc printf("userPrincipalName %s\n", vals[0]); 948*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "userAccountControl"); 949*ebfedea0SLionel Sambuc if (vals) 950*ebfedea0SLionel Sambuc printf("userAccountControl %s\n", vals[0]); 951*ebfedea0SLionel Sambuc #endif 952*ebfedea0SLionel Sambuc entry->princ_expire_time = 0; 953*ebfedea0SLionel Sambuc if (mask & KADM5_PRINC_EXPIRE_TIME) { 954*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "accountExpires"); 955*ebfedea0SLionel Sambuc if (vals) 956*ebfedea0SLionel Sambuc entry->princ_expire_time = nt2unixtime(vals[0]); 957*ebfedea0SLionel Sambuc } 958*ebfedea0SLionel Sambuc entry->last_success = 0; 959*ebfedea0SLionel Sambuc if (mask & KADM5_LAST_SUCCESS) { 960*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "lastLogon"); 961*ebfedea0SLionel Sambuc if (vals) 962*ebfedea0SLionel Sambuc entry->last_success = nt2unixtime(vals[0]); 963*ebfedea0SLionel Sambuc } 964*ebfedea0SLionel Sambuc if (mask & KADM5_LAST_FAILED) { 965*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "badPasswordTime"); 966*ebfedea0SLionel Sambuc if (vals) 967*ebfedea0SLionel Sambuc entry->last_failed = nt2unixtime(vals[0]); 968*ebfedea0SLionel Sambuc } 969*ebfedea0SLionel Sambuc if (mask & KADM5_LAST_PWD_CHANGE) { 970*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "pwdLastSet"); 971*ebfedea0SLionel Sambuc if (vals) 972*ebfedea0SLionel Sambuc entry->last_pwd_change = nt2unixtime(vals[0]); 973*ebfedea0SLionel Sambuc } 974*ebfedea0SLionel Sambuc if (mask & KADM5_FAIL_AUTH_COUNT) { 975*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "badPwdCount"); 976*ebfedea0SLionel Sambuc if (vals) 977*ebfedea0SLionel Sambuc entry->fail_auth_count = atoi(vals[0]); 978*ebfedea0SLionel Sambuc } 979*ebfedea0SLionel Sambuc if (mask & KADM5_ATTRIBUTES) { 980*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "userAccountControl"); 981*ebfedea0SLionel Sambuc if (vals) { 982*ebfedea0SLionel Sambuc uint32_t i; 983*ebfedea0SLionel Sambuc i = atoi(vals[0]); 984*ebfedea0SLionel Sambuc if (i & (UF_ACCOUNTDISABLE|UF_LOCKOUT)) 985*ebfedea0SLionel Sambuc entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX; 986*ebfedea0SLionel Sambuc if ((i & UF_DONT_REQUIRE_PREAUTH) == 0) 987*ebfedea0SLionel Sambuc entry->attributes |= KRB5_KDB_REQUIRES_PRE_AUTH; 988*ebfedea0SLionel Sambuc if (i & UF_SMARTCARD_REQUIRED) 989*ebfedea0SLionel Sambuc entry->attributes |= KRB5_KDB_REQUIRES_HW_AUTH; 990*ebfedea0SLionel Sambuc if ((i & UF_WORKSTATION_TRUST_ACCOUNT) == 0) 991*ebfedea0SLionel Sambuc entry->attributes |= KRB5_KDB_DISALLOW_SVR; 992*ebfedea0SLionel Sambuc } 993*ebfedea0SLionel Sambuc } 994*ebfedea0SLionel Sambuc if (mask & KADM5_KVNO) { 995*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, 996*ebfedea0SLionel Sambuc "msDS-KeyVersionNumber"); 997*ebfedea0SLionel Sambuc if (vals) 998*ebfedea0SLionel Sambuc entry->kvno = atoi(vals[0]); 999*ebfedea0SLionel Sambuc else 1000*ebfedea0SLionel Sambuc entry->kvno = 0; 1001*ebfedea0SLionel Sambuc } 1002*ebfedea0SLionel Sambuc ldap_msgfree(m); 1003*ebfedea0SLionel Sambuc } else { 1004*ebfedea0SLionel Sambuc return KADM5_UNK_PRINC; 1005*ebfedea0SLionel Sambuc } 1006*ebfedea0SLionel Sambuc 1007*ebfedea0SLionel Sambuc if (mask & KADM5_PRINCIPAL) 1008*ebfedea0SLionel Sambuc krb5_copy_principal(context->context, principal, &entry->principal); 1009*ebfedea0SLionel Sambuc 1010*ebfedea0SLionel Sambuc return 0; 1011*ebfedea0SLionel Sambuc fail: 1012*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1013*ebfedea0SLionel Sambuc #else 1014*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1015*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1016*ebfedea0SLionel Sambuc #endif 1017*ebfedea0SLionel Sambuc } 1018*ebfedea0SLionel Sambuc 1019*ebfedea0SLionel Sambuc static kadm5_ret_t 1020*ebfedea0SLionel Sambuc kadm5_ad_get_principals(void *server_handle, 1021*ebfedea0SLionel Sambuc const char *expression, 1022*ebfedea0SLionel Sambuc char ***principals, 1023*ebfedea0SLionel Sambuc int *count) 1024*ebfedea0SLionel Sambuc { 1025*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 1026*ebfedea0SLionel Sambuc 1027*ebfedea0SLionel Sambuc /* 1028*ebfedea0SLionel Sambuc * KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES 1029*ebfedea0SLionel Sambuc */ 1030*ebfedea0SLionel Sambuc 1031*ebfedea0SLionel Sambuc #ifdef OPENLDAP 1032*ebfedea0SLionel Sambuc kadm5_ret_t ret; 1033*ebfedea0SLionel Sambuc 1034*ebfedea0SLionel Sambuc ret = ad_get_cred(context, NULL); 1035*ebfedea0SLionel Sambuc if (ret) 1036*ebfedea0SLionel Sambuc return ret; 1037*ebfedea0SLionel Sambuc 1038*ebfedea0SLionel Sambuc ret = _kadm5_ad_connect(server_handle); 1039*ebfedea0SLionel Sambuc if (ret) 1040*ebfedea0SLionel Sambuc return ret; 1041*ebfedea0SLionel Sambuc 1042*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1043*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1044*ebfedea0SLionel Sambuc #else 1045*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1046*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1047*ebfedea0SLionel Sambuc #endif 1048*ebfedea0SLionel Sambuc } 1049*ebfedea0SLionel Sambuc 1050*ebfedea0SLionel Sambuc static kadm5_ret_t 1051*ebfedea0SLionel Sambuc kadm5_ad_get_privs(void *server_handle, uint32_t*privs) 1052*ebfedea0SLionel Sambuc { 1053*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 1054*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1055*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1056*ebfedea0SLionel Sambuc } 1057*ebfedea0SLionel Sambuc 1058*ebfedea0SLionel Sambuc static kadm5_ret_t 1059*ebfedea0SLionel Sambuc kadm5_ad_modify_principal(void *server_handle, 1060*ebfedea0SLionel Sambuc kadm5_principal_ent_t entry, 1061*ebfedea0SLionel Sambuc uint32_t mask) 1062*ebfedea0SLionel Sambuc { 1063*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 1064*ebfedea0SLionel Sambuc 1065*ebfedea0SLionel Sambuc /* 1066*ebfedea0SLionel Sambuc * KADM5_ATTRIBUTES 1067*ebfedea0SLionel Sambuc * KRB5_KDB_DISALLOW_ALL_TIX (| KADM5_KVNO) 1068*ebfedea0SLionel Sambuc */ 1069*ebfedea0SLionel Sambuc 1070*ebfedea0SLionel Sambuc #ifdef OPENLDAP 1071*ebfedea0SLionel Sambuc LDAPMessage *m = NULL, *m0; 1072*ebfedea0SLionel Sambuc kadm5_ret_t ret; 1073*ebfedea0SLionel Sambuc char **attr = NULL; 1074*ebfedea0SLionel Sambuc int attrlen = 0; 1075*ebfedea0SLionel Sambuc char *p = NULL, *s = NULL, *q; 1076*ebfedea0SLionel Sambuc char **vals; 1077*ebfedea0SLionel Sambuc LDAPMod *attrs[4], rattrs[3], *a; 1078*ebfedea0SLionel Sambuc char *uaf[2] = { NULL, NULL }; 1079*ebfedea0SLionel Sambuc char *kvno[2] = { NULL, NULL }; 1080*ebfedea0SLionel Sambuc char *tv[2] = { NULL, NULL }; 1081*ebfedea0SLionel Sambuc char *filter, *dn; 1082*ebfedea0SLionel Sambuc int i; 1083*ebfedea0SLionel Sambuc 1084*ebfedea0SLionel Sambuc for (i = 0; i < sizeof(rattrs)/sizeof(rattrs[0]); i++) 1085*ebfedea0SLionel Sambuc attrs[i] = &rattrs[i]; 1086*ebfedea0SLionel Sambuc attrs[i] = NULL; 1087*ebfedea0SLionel Sambuc a = &rattrs[0]; 1088*ebfedea0SLionel Sambuc 1089*ebfedea0SLionel Sambuc ret = _kadm5_ad_connect(server_handle); 1090*ebfedea0SLionel Sambuc if (ret) 1091*ebfedea0SLionel Sambuc return ret; 1092*ebfedea0SLionel Sambuc 1093*ebfedea0SLionel Sambuc if (mask & KADM5_KVNO) 1094*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "msDS-KeyVersionNumber"); 1095*ebfedea0SLionel Sambuc if (mask & KADM5_PRINC_EXPIRE_TIME) 1096*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "accountExpires"); 1097*ebfedea0SLionel Sambuc if (mask & KADM5_ATTRIBUTES) 1098*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "userAccountControl"); 1099*ebfedea0SLionel Sambuc laddattr(&attr, &attrlen, "distinguishedName"); 1100*ebfedea0SLionel Sambuc 1101*ebfedea0SLionel Sambuc krb5_unparse_name(context->context, entry->principal, &p); 1102*ebfedea0SLionel Sambuc 1103*ebfedea0SLionel Sambuc s = strdup(p); 1104*ebfedea0SLionel Sambuc 1105*ebfedea0SLionel Sambuc q = strrchr(s, '@'); 1106*ebfedea0SLionel Sambuc if (q && (p != q && *(q - 1) != '\\')) 1107*ebfedea0SLionel Sambuc *q = '\0'; 1108*ebfedea0SLionel Sambuc 1109*ebfedea0SLionel Sambuc asprintf(&filter, 1110*ebfedea0SLionel Sambuc "(|(userPrincipalName=%s)(servicePrincipalName=%s))", 1111*ebfedea0SLionel Sambuc s, s); 1112*ebfedea0SLionel Sambuc free(p); 1113*ebfedea0SLionel Sambuc free(s); 1114*ebfedea0SLionel Sambuc 1115*ebfedea0SLionel Sambuc ret = ldap_search_s(CTX2LP(context), CTX2BASE(context), 1116*ebfedea0SLionel Sambuc LDAP_SCOPE_SUBTREE, 1117*ebfedea0SLionel Sambuc filter, attr, 0, &m); 1118*ebfedea0SLionel Sambuc free(attr); 1119*ebfedea0SLionel Sambuc free(filter); 1120*ebfedea0SLionel Sambuc if (check_ldap(context, ret)) 1121*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1122*ebfedea0SLionel Sambuc 1123*ebfedea0SLionel Sambuc if (ldap_count_entries(CTX2LP(context), m) <= 0) { 1124*ebfedea0SLionel Sambuc ret = KADM5_RPC_ERROR; 1125*ebfedea0SLionel Sambuc goto out; 1126*ebfedea0SLionel Sambuc } 1127*ebfedea0SLionel Sambuc 1128*ebfedea0SLionel Sambuc m0 = ldap_first_entry(CTX2LP(context), m); 1129*ebfedea0SLionel Sambuc 1130*ebfedea0SLionel Sambuc if (mask & KADM5_ATTRIBUTES) { 1131*ebfedea0SLionel Sambuc int32_t i; 1132*ebfedea0SLionel Sambuc 1133*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "userAccountControl"); 1134*ebfedea0SLionel Sambuc if (vals == NULL) { 1135*ebfedea0SLionel Sambuc ret = KADM5_RPC_ERROR; 1136*ebfedea0SLionel Sambuc goto out; 1137*ebfedea0SLionel Sambuc } 1138*ebfedea0SLionel Sambuc 1139*ebfedea0SLionel Sambuc i = atoi(vals[0]); 1140*ebfedea0SLionel Sambuc if (i == 0) 1141*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1142*ebfedea0SLionel Sambuc 1143*ebfedea0SLionel Sambuc if (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX) 1144*ebfedea0SLionel Sambuc i |= (UF_ACCOUNTDISABLE|UF_LOCKOUT); 1145*ebfedea0SLionel Sambuc else 1146*ebfedea0SLionel Sambuc i &= ~(UF_ACCOUNTDISABLE|UF_LOCKOUT); 1147*ebfedea0SLionel Sambuc if (entry->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) 1148*ebfedea0SLionel Sambuc i &= ~UF_DONT_REQUIRE_PREAUTH; 1149*ebfedea0SLionel Sambuc else 1150*ebfedea0SLionel Sambuc i |= UF_DONT_REQUIRE_PREAUTH; 1151*ebfedea0SLionel Sambuc if (entry->attributes & KRB5_KDB_REQUIRES_HW_AUTH) 1152*ebfedea0SLionel Sambuc i |= UF_SMARTCARD_REQUIRED; 1153*ebfedea0SLionel Sambuc else 1154*ebfedea0SLionel Sambuc i &= UF_SMARTCARD_REQUIRED; 1155*ebfedea0SLionel Sambuc if (entry->attributes & KRB5_KDB_DISALLOW_SVR) 1156*ebfedea0SLionel Sambuc i &= ~UF_WORKSTATION_TRUST_ACCOUNT; 1157*ebfedea0SLionel Sambuc else 1158*ebfedea0SLionel Sambuc i |= UF_WORKSTATION_TRUST_ACCOUNT; 1159*ebfedea0SLionel Sambuc 1160*ebfedea0SLionel Sambuc asprintf(&uaf[0], "%d", i); 1161*ebfedea0SLionel Sambuc 1162*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_REPLACE; 1163*ebfedea0SLionel Sambuc a->mod_type = "userAccountControl"; 1164*ebfedea0SLionel Sambuc a->mod_values = uaf; 1165*ebfedea0SLionel Sambuc a++; 1166*ebfedea0SLionel Sambuc } 1167*ebfedea0SLionel Sambuc 1168*ebfedea0SLionel Sambuc if (mask & KADM5_KVNO) { 1169*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "msDS-KeyVersionNumber"); 1170*ebfedea0SLionel Sambuc if (vals == NULL) { 1171*ebfedea0SLionel Sambuc entry->kvno = 0; 1172*ebfedea0SLionel Sambuc } else { 1173*ebfedea0SLionel Sambuc asprintf(&kvno[0], "%d", entry->kvno); 1174*ebfedea0SLionel Sambuc 1175*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_REPLACE; 1176*ebfedea0SLionel Sambuc a->mod_type = "msDS-KeyVersionNumber"; 1177*ebfedea0SLionel Sambuc a->mod_values = kvno; 1178*ebfedea0SLionel Sambuc a++; 1179*ebfedea0SLionel Sambuc } 1180*ebfedea0SLionel Sambuc } 1181*ebfedea0SLionel Sambuc 1182*ebfedea0SLionel Sambuc if (mask & KADM5_PRINC_EXPIRE_TIME) { 1183*ebfedea0SLionel Sambuc long long wt; 1184*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "accountExpires"); 1185*ebfedea0SLionel Sambuc if (vals == NULL) { 1186*ebfedea0SLionel Sambuc ret = KADM5_RPC_ERROR; 1187*ebfedea0SLionel Sambuc goto out; 1188*ebfedea0SLionel Sambuc } 1189*ebfedea0SLionel Sambuc 1190*ebfedea0SLionel Sambuc wt = unix2nttime(entry->princ_expire_time); 1191*ebfedea0SLionel Sambuc 1192*ebfedea0SLionel Sambuc asprintf(&tv[0], "%llu", wt); 1193*ebfedea0SLionel Sambuc 1194*ebfedea0SLionel Sambuc a->mod_op = LDAP_MOD_REPLACE; 1195*ebfedea0SLionel Sambuc a->mod_type = "accountExpires"; 1196*ebfedea0SLionel Sambuc a->mod_values = tv; 1197*ebfedea0SLionel Sambuc a++; 1198*ebfedea0SLionel Sambuc } 1199*ebfedea0SLionel Sambuc 1200*ebfedea0SLionel Sambuc vals = ldap_get_values(CTX2LP(context), m0, "distinguishedName"); 1201*ebfedea0SLionel Sambuc if (vals == NULL) { 1202*ebfedea0SLionel Sambuc ret = KADM5_RPC_ERROR; 1203*ebfedea0SLionel Sambuc goto out; 1204*ebfedea0SLionel Sambuc } 1205*ebfedea0SLionel Sambuc dn = vals[0]; 1206*ebfedea0SLionel Sambuc 1207*ebfedea0SLionel Sambuc attrs[a - &rattrs[0]] = NULL; 1208*ebfedea0SLionel Sambuc 1209*ebfedea0SLionel Sambuc ret = ldap_modify_s(CTX2LP(context), dn, attrs); 1210*ebfedea0SLionel Sambuc if (check_ldap(context, ret)) 1211*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1212*ebfedea0SLionel Sambuc 1213*ebfedea0SLionel Sambuc out: 1214*ebfedea0SLionel Sambuc if (m) 1215*ebfedea0SLionel Sambuc ldap_msgfree(m); 1216*ebfedea0SLionel Sambuc if (uaf[0]) 1217*ebfedea0SLionel Sambuc free(uaf[0]); 1218*ebfedea0SLionel Sambuc if (kvno[0]) 1219*ebfedea0SLionel Sambuc free(kvno[0]); 1220*ebfedea0SLionel Sambuc if (tv[0]) 1221*ebfedea0SLionel Sambuc free(tv[0]); 1222*ebfedea0SLionel Sambuc return ret; 1223*ebfedea0SLionel Sambuc #else 1224*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1225*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1226*ebfedea0SLionel Sambuc #endif 1227*ebfedea0SLionel Sambuc } 1228*ebfedea0SLionel Sambuc 1229*ebfedea0SLionel Sambuc static kadm5_ret_t 1230*ebfedea0SLionel Sambuc kadm5_ad_randkey_principal(void *server_handle, 1231*ebfedea0SLionel Sambuc krb5_principal principal, 1232*ebfedea0SLionel Sambuc krb5_keyblock **keys, 1233*ebfedea0SLionel Sambuc int *n_keys) 1234*ebfedea0SLionel Sambuc { 1235*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 1236*ebfedea0SLionel Sambuc 1237*ebfedea0SLionel Sambuc /* 1238*ebfedea0SLionel Sambuc * random key 1239*ebfedea0SLionel Sambuc */ 1240*ebfedea0SLionel Sambuc 1241*ebfedea0SLionel Sambuc #ifdef OPENLDAP 1242*ebfedea0SLionel Sambuc krb5_data result_code_string, result_string; 1243*ebfedea0SLionel Sambuc int result_code, plen; 1244*ebfedea0SLionel Sambuc kadm5_ret_t ret; 1245*ebfedea0SLionel Sambuc char *password; 1246*ebfedea0SLionel Sambuc 1247*ebfedea0SLionel Sambuc *keys = NULL; 1248*ebfedea0SLionel Sambuc *n_keys = 0; 1249*ebfedea0SLionel Sambuc 1250*ebfedea0SLionel Sambuc { 1251*ebfedea0SLionel Sambuc char p[64]; 1252*ebfedea0SLionel Sambuc krb5_generate_random_block(p, sizeof(p)); 1253*ebfedea0SLionel Sambuc plen = base64_encode(p, sizeof(p), &password); 1254*ebfedea0SLionel Sambuc if (plen < 0) 1255*ebfedea0SLionel Sambuc return ENOMEM; 1256*ebfedea0SLionel Sambuc } 1257*ebfedea0SLionel Sambuc 1258*ebfedea0SLionel Sambuc ret = ad_get_cred(context, NULL); 1259*ebfedea0SLionel Sambuc if (ret) { 1260*ebfedea0SLionel Sambuc free(password); 1261*ebfedea0SLionel Sambuc return ret; 1262*ebfedea0SLionel Sambuc } 1263*ebfedea0SLionel Sambuc 1264*ebfedea0SLionel Sambuc krb5_data_zero (&result_code_string); 1265*ebfedea0SLionel Sambuc krb5_data_zero (&result_string); 1266*ebfedea0SLionel Sambuc 1267*ebfedea0SLionel Sambuc ret = krb5_set_password_using_ccache (context->context, 1268*ebfedea0SLionel Sambuc context->ccache, 1269*ebfedea0SLionel Sambuc password, 1270*ebfedea0SLionel Sambuc principal, 1271*ebfedea0SLionel Sambuc &result_code, 1272*ebfedea0SLionel Sambuc &result_code_string, 1273*ebfedea0SLionel Sambuc &result_string); 1274*ebfedea0SLionel Sambuc 1275*ebfedea0SLionel Sambuc krb5_data_free (&result_code_string); 1276*ebfedea0SLionel Sambuc krb5_data_free (&result_string); 1277*ebfedea0SLionel Sambuc 1278*ebfedea0SLionel Sambuc if (ret == 0) { 1279*ebfedea0SLionel Sambuc 1280*ebfedea0SLionel Sambuc *keys = malloc(sizeof(**keys) * 1); 1281*ebfedea0SLionel Sambuc if (*keys == NULL) { 1282*ebfedea0SLionel Sambuc ret = ENOMEM; 1283*ebfedea0SLionel Sambuc goto out; 1284*ebfedea0SLionel Sambuc } 1285*ebfedea0SLionel Sambuc *n_keys = 1; 1286*ebfedea0SLionel Sambuc 1287*ebfedea0SLionel Sambuc ret = krb5_string_to_key(context->context, 1288*ebfedea0SLionel Sambuc ENCTYPE_ARCFOUR_HMAC_MD5, 1289*ebfedea0SLionel Sambuc password, 1290*ebfedea0SLionel Sambuc principal, 1291*ebfedea0SLionel Sambuc &(*keys)[0]); 1292*ebfedea0SLionel Sambuc memset(password, 0, sizeof(password)); 1293*ebfedea0SLionel Sambuc if (ret) { 1294*ebfedea0SLionel Sambuc free(*keys); 1295*ebfedea0SLionel Sambuc *keys = NULL; 1296*ebfedea0SLionel Sambuc *n_keys = 0; 1297*ebfedea0SLionel Sambuc goto out; 1298*ebfedea0SLionel Sambuc } 1299*ebfedea0SLionel Sambuc } 1300*ebfedea0SLionel Sambuc memset(password, 0, plen); 1301*ebfedea0SLionel Sambuc free(password); 1302*ebfedea0SLionel Sambuc out: 1303*ebfedea0SLionel Sambuc return ret; 1304*ebfedea0SLionel Sambuc #else 1305*ebfedea0SLionel Sambuc *keys = NULL; 1306*ebfedea0SLionel Sambuc *n_keys = 0; 1307*ebfedea0SLionel Sambuc 1308*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1309*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1310*ebfedea0SLionel Sambuc #endif 1311*ebfedea0SLionel Sambuc } 1312*ebfedea0SLionel Sambuc 1313*ebfedea0SLionel Sambuc static kadm5_ret_t 1314*ebfedea0SLionel Sambuc kadm5_ad_rename_principal(void *server_handle, 1315*ebfedea0SLionel Sambuc krb5_principal from, 1316*ebfedea0SLionel Sambuc krb5_principal to) 1317*ebfedea0SLionel Sambuc { 1318*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 1319*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1320*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1321*ebfedea0SLionel Sambuc } 1322*ebfedea0SLionel Sambuc 1323*ebfedea0SLionel Sambuc static kadm5_ret_t 1324*ebfedea0SLionel Sambuc kadm5_ad_chpass_principal_with_key(void *server_handle, 1325*ebfedea0SLionel Sambuc krb5_principal princ, 1326*ebfedea0SLionel Sambuc int n_key_data, 1327*ebfedea0SLionel Sambuc krb5_key_data *key_data) 1328*ebfedea0SLionel Sambuc { 1329*ebfedea0SLionel Sambuc kadm5_ad_context *context = server_handle; 1330*ebfedea0SLionel Sambuc krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); 1331*ebfedea0SLionel Sambuc return KADM5_RPC_ERROR; 1332*ebfedea0SLionel Sambuc } 1333*ebfedea0SLionel Sambuc 1334*ebfedea0SLionel Sambuc static void 1335*ebfedea0SLionel Sambuc set_funcs(kadm5_ad_context *c) 1336*ebfedea0SLionel Sambuc { 1337*ebfedea0SLionel Sambuc #define SET(C, F) (C)->funcs.F = kadm5_ad_ ## F 1338*ebfedea0SLionel Sambuc SET(c, chpass_principal); 1339*ebfedea0SLionel Sambuc SET(c, chpass_principal_with_key); 1340*ebfedea0SLionel Sambuc SET(c, create_principal); 1341*ebfedea0SLionel Sambuc SET(c, delete_principal); 1342*ebfedea0SLionel Sambuc SET(c, destroy); 1343*ebfedea0SLionel Sambuc SET(c, flush); 1344*ebfedea0SLionel Sambuc SET(c, get_principal); 1345*ebfedea0SLionel Sambuc SET(c, get_principals); 1346*ebfedea0SLionel Sambuc SET(c, get_privs); 1347*ebfedea0SLionel Sambuc SET(c, modify_principal); 1348*ebfedea0SLionel Sambuc SET(c, randkey_principal); 1349*ebfedea0SLionel Sambuc SET(c, rename_principal); 1350*ebfedea0SLionel Sambuc } 1351*ebfedea0SLionel Sambuc 1352*ebfedea0SLionel Sambuc kadm5_ret_t 1353*ebfedea0SLionel Sambuc kadm5_ad_init_with_password_ctx(krb5_context context, 1354*ebfedea0SLionel Sambuc const char *client_name, 1355*ebfedea0SLionel Sambuc const char *password, 1356*ebfedea0SLionel Sambuc const char *service_name, 1357*ebfedea0SLionel Sambuc kadm5_config_params *realm_params, 1358*ebfedea0SLionel Sambuc unsigned long struct_version, 1359*ebfedea0SLionel Sambuc unsigned long api_version, 1360*ebfedea0SLionel Sambuc void **server_handle) 1361*ebfedea0SLionel Sambuc { 1362*ebfedea0SLionel Sambuc kadm5_ret_t ret; 1363*ebfedea0SLionel Sambuc kadm5_ad_context *ctx; 1364*ebfedea0SLionel Sambuc 1365*ebfedea0SLionel Sambuc ctx = malloc(sizeof(*ctx)); 1366*ebfedea0SLionel Sambuc if(ctx == NULL) 1367*ebfedea0SLionel Sambuc return ENOMEM; 1368*ebfedea0SLionel Sambuc memset(ctx, 0, sizeof(*ctx)); 1369*ebfedea0SLionel Sambuc set_funcs(ctx); 1370*ebfedea0SLionel Sambuc 1371*ebfedea0SLionel Sambuc ctx->context = context; 1372*ebfedea0SLionel Sambuc krb5_add_et_list (context, initialize_kadm5_error_table_r); 1373*ebfedea0SLionel Sambuc 1374*ebfedea0SLionel Sambuc ret = krb5_parse_name(ctx->context, client_name, &ctx->caller); 1375*ebfedea0SLionel Sambuc if(ret) { 1376*ebfedea0SLionel Sambuc free(ctx); 1377*ebfedea0SLionel Sambuc return ret; 1378*ebfedea0SLionel Sambuc } 1379*ebfedea0SLionel Sambuc 1380*ebfedea0SLionel Sambuc if(realm_params->mask & KADM5_CONFIG_REALM) { 1381*ebfedea0SLionel Sambuc ret = 0; 1382*ebfedea0SLionel Sambuc ctx->realm = strdup(realm_params->realm); 1383*ebfedea0SLionel Sambuc if (ctx->realm == NULL) 1384*ebfedea0SLionel Sambuc ret = ENOMEM; 1385*ebfedea0SLionel Sambuc } else 1386*ebfedea0SLionel Sambuc ret = krb5_get_default_realm(ctx->context, &ctx->realm); 1387*ebfedea0SLionel Sambuc if (ret) { 1388*ebfedea0SLionel Sambuc free(ctx); 1389*ebfedea0SLionel Sambuc return ret; 1390*ebfedea0SLionel Sambuc } 1391*ebfedea0SLionel Sambuc 1392*ebfedea0SLionel Sambuc ctx->client_name = strdup(client_name); 1393*ebfedea0SLionel Sambuc 1394*ebfedea0SLionel Sambuc if(password != NULL && *password != '\0') 1395*ebfedea0SLionel Sambuc ret = ad_get_cred(ctx, password); 1396*ebfedea0SLionel Sambuc else 1397*ebfedea0SLionel Sambuc ret = ad_get_cred(ctx, NULL); 1398*ebfedea0SLionel Sambuc if(ret) { 1399*ebfedea0SLionel Sambuc kadm5_ad_destroy(ctx); 1400*ebfedea0SLionel Sambuc return ret; 1401*ebfedea0SLionel Sambuc } 1402*ebfedea0SLionel Sambuc 1403*ebfedea0SLionel Sambuc #ifdef OPENLDAP 1404*ebfedea0SLionel Sambuc ret = _kadm5_ad_connect(ctx); 1405*ebfedea0SLionel Sambuc if (ret) { 1406*ebfedea0SLionel Sambuc kadm5_ad_destroy(ctx); 1407*ebfedea0SLionel Sambuc return ret; 1408*ebfedea0SLionel Sambuc } 1409*ebfedea0SLionel Sambuc #endif 1410*ebfedea0SLionel Sambuc 1411*ebfedea0SLionel Sambuc *server_handle = ctx; 1412*ebfedea0SLionel Sambuc return 0; 1413*ebfedea0SLionel Sambuc } 1414*ebfedea0SLionel Sambuc 1415*ebfedea0SLionel Sambuc kadm5_ret_t 1416*ebfedea0SLionel Sambuc kadm5_ad_init_with_password(const char *client_name, 1417*ebfedea0SLionel Sambuc const char *password, 1418*ebfedea0SLionel Sambuc const char *service_name, 1419*ebfedea0SLionel Sambuc kadm5_config_params *realm_params, 1420*ebfedea0SLionel Sambuc unsigned long struct_version, 1421*ebfedea0SLionel Sambuc unsigned long api_version, 1422*ebfedea0SLionel Sambuc void **server_handle) 1423*ebfedea0SLionel Sambuc { 1424*ebfedea0SLionel Sambuc krb5_context context; 1425*ebfedea0SLionel Sambuc kadm5_ret_t ret; 1426*ebfedea0SLionel Sambuc kadm5_ad_context *ctx; 1427*ebfedea0SLionel Sambuc 1428*ebfedea0SLionel Sambuc ret = krb5_init_context(&context); 1429*ebfedea0SLionel Sambuc if (ret) 1430*ebfedea0SLionel Sambuc return ret; 1431*ebfedea0SLionel Sambuc ret = kadm5_ad_init_with_password_ctx(context, 1432*ebfedea0SLionel Sambuc client_name, 1433*ebfedea0SLionel Sambuc password, 1434*ebfedea0SLionel Sambuc service_name, 1435*ebfedea0SLionel Sambuc realm_params, 1436*ebfedea0SLionel Sambuc struct_version, 1437*ebfedea0SLionel Sambuc api_version, 1438*ebfedea0SLionel Sambuc server_handle); 1439*ebfedea0SLionel Sambuc if(ret) { 1440*ebfedea0SLionel Sambuc krb5_free_context(context); 1441*ebfedea0SLionel Sambuc return ret; 1442*ebfedea0SLionel Sambuc } 1443*ebfedea0SLionel Sambuc ctx = *server_handle; 1444*ebfedea0SLionel Sambuc ctx->my_context = 1; 1445*ebfedea0SLionel Sambuc return 0; 1446*ebfedea0SLionel Sambuc } 1447