1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gate #include <stdio.h> 10*0Sstevel@tonic-gate #include <stdlib.h> /* getenv, exit */ 11*0Sstevel@tonic-gate #include <signal.h> 12*0Sstevel@tonic-gate #include <sys/types.h> 13*0Sstevel@tonic-gate #include <memory.h> 14*0Sstevel@tonic-gate #include <stropts.h> 15*0Sstevel@tonic-gate #include <netconfig.h> 16*0Sstevel@tonic-gate #include <sys/resource.h> /* rlimit */ 17*0Sstevel@tonic-gate #include <syslog.h> 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gate #include <kadm5/admin.h> 20*0Sstevel@tonic-gate #include <kadm5/kadm_rpc.h> 21*0Sstevel@tonic-gate #include <kadm5/server_internal.h> 22*0Sstevel@tonic-gate #include <server_acl.h> 23*0Sstevel@tonic-gate #include <krb5/adm_proto.h> 24*0Sstevel@tonic-gate #include <string.h> 25*0Sstevel@tonic-gate #include <gssapi_krb5.h> 26*0Sstevel@tonic-gate #include <sys/socket.h> 27*0Sstevel@tonic-gate #include <netinet/in.h> 28*0Sstevel@tonic-gate #include <arpa/inet.h> 29*0Sstevel@tonic-gate #include <netdb.h> 30*0Sstevel@tonic-gate #include <libintl.h> 31*0Sstevel@tonic-gate #include <kdb/kdb_log.h> 32*0Sstevel@tonic-gate #include "misc.h" 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate extern int setup_gss_names(struct svc_req *, char **, char **); 37*0Sstevel@tonic-gate extern gss_name_t get_clnt_name(struct svc_req *); 38*0Sstevel@tonic-gate extern char *client_addr(struct svc_req *, char *); 39*0Sstevel@tonic-gate extern void *global_server_handle; 40*0Sstevel@tonic-gate extern int nofork; 41*0Sstevel@tonic-gate extern short l_port; 42*0Sstevel@tonic-gate static char abuf[33]; 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate static char *reply_ok_str = "UPDATE_OK"; 45*0Sstevel@tonic-gate static char *reply_err_str = "UPDATE_ERROR"; 46*0Sstevel@tonic-gate static char *reply_fr_str = "UPDATE_FULL_RESYNC_NEEDED"; 47*0Sstevel@tonic-gate static char *reply_busy_str = "UPDATE_BUSY"; 48*0Sstevel@tonic-gate static char *reply_nil_str = "UPDATE_NIL"; 49*0Sstevel@tonic-gate static char *reply_perm_str = "UPDATE_PERM_DENIED"; 50*0Sstevel@tonic-gate static char *reply_unknown_str = "<UNKNOWN_CODE>"; 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate #define LOG_UNAUTH gettext("Unauthorized request: %s, %s, " \ 53*0Sstevel@tonic-gate "client=%s, service=%s, addr=%s") 54*0Sstevel@tonic-gate #define LOG_DONE gettext("Request: %s, %s, %s, client=%s, " \ 55*0Sstevel@tonic-gate "service=%s, addr=%s") 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate #define KDB5_UTIL_DUMP_STR "/usr/sbin/kdb5_util dump -i " 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #ifdef DPRINT 60*0Sstevel@tonic-gate #undef DPRINT 61*0Sstevel@tonic-gate #endif 62*0Sstevel@tonic-gate #define DPRINT(i) if (nofork) printf i 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate static void 66*0Sstevel@tonic-gate debprret(char *w, update_status_t ret, kdb_sno_t sno) 67*0Sstevel@tonic-gate { 68*0Sstevel@tonic-gate switch (ret) { 69*0Sstevel@tonic-gate case UPDATE_OK: 70*0Sstevel@tonic-gate printf("%s: end (OK, sno=%u)\n", 71*0Sstevel@tonic-gate w, sno); 72*0Sstevel@tonic-gate break; 73*0Sstevel@tonic-gate case UPDATE_ERROR: 74*0Sstevel@tonic-gate printf("%s: end (ERROR)\n", w); 75*0Sstevel@tonic-gate break; 76*0Sstevel@tonic-gate case UPDATE_FULL_RESYNC_NEEDED: 77*0Sstevel@tonic-gate printf("%s: end (FR NEEDED)\n", w); 78*0Sstevel@tonic-gate break; 79*0Sstevel@tonic-gate case UPDATE_BUSY: 80*0Sstevel@tonic-gate printf("%s: end (BUSY)\n", w); 81*0Sstevel@tonic-gate break; 82*0Sstevel@tonic-gate case UPDATE_NIL: 83*0Sstevel@tonic-gate printf("%s: end (NIL)\n", w); 84*0Sstevel@tonic-gate break; 85*0Sstevel@tonic-gate case UPDATE_PERM_DENIED: 86*0Sstevel@tonic-gate printf("%s: end (PERM)\n", w); 87*0Sstevel@tonic-gate break; 88*0Sstevel@tonic-gate default: 89*0Sstevel@tonic-gate printf("%s: end (UNKNOWN return code (%d))\n", w, ret); 90*0Sstevel@tonic-gate } 91*0Sstevel@tonic-gate } 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate static char * 94*0Sstevel@tonic-gate replystr(update_status_t ret) 95*0Sstevel@tonic-gate { 96*0Sstevel@tonic-gate switch (ret) { 97*0Sstevel@tonic-gate case UPDATE_OK: 98*0Sstevel@tonic-gate return (reply_ok_str); 99*0Sstevel@tonic-gate case UPDATE_ERROR: 100*0Sstevel@tonic-gate return (reply_err_str); 101*0Sstevel@tonic-gate case UPDATE_FULL_RESYNC_NEEDED: 102*0Sstevel@tonic-gate return (reply_fr_str); 103*0Sstevel@tonic-gate case UPDATE_BUSY: 104*0Sstevel@tonic-gate return (reply_busy_str); 105*0Sstevel@tonic-gate case UPDATE_NIL: 106*0Sstevel@tonic-gate return (reply_nil_str); 107*0Sstevel@tonic-gate case UPDATE_PERM_DENIED: 108*0Sstevel@tonic-gate return (reply_perm_str); 109*0Sstevel@tonic-gate default: 110*0Sstevel@tonic-gate return (reply_unknown_str); 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate kdb_incr_result_t * 115*0Sstevel@tonic-gate iprop_get_updates_1(kdb_last_t *arg, struct svc_req *rqstp) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate static kdb_incr_result_t ret; 118*0Sstevel@tonic-gate char *whoami = "iprop_get_updates_1"; 119*0Sstevel@tonic-gate int kret; 120*0Sstevel@tonic-gate kadm5_server_handle_t handle = global_server_handle; 121*0Sstevel@tonic-gate char *client_name = NULL, *service_name = NULL; 122*0Sstevel@tonic-gate gss_name_t name = NULL; 123*0Sstevel@tonic-gate OM_uint32 min_stat; 124*0Sstevel@tonic-gate char obuf[256] = {0}; 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate /* default return code */ 127*0Sstevel@tonic-gate ret.ret = UPDATE_ERROR; 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate DPRINT(("%s: start, last_sno=%u\n", whoami, (ulong_t)arg->last_sno)); 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate if (!handle) { 132*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 133*0Sstevel@tonic-gate gettext("%s: server handle is NULL"), 134*0Sstevel@tonic-gate whoami); 135*0Sstevel@tonic-gate goto out; 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 139*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 140*0Sstevel@tonic-gate gettext("%s: setup_gss_names failed"), 141*0Sstevel@tonic-gate whoami); 142*0Sstevel@tonic-gate goto out; 143*0Sstevel@tonic-gate } 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate DPRINT(("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n", 146*0Sstevel@tonic-gate whoami, client_name, service_name)); 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate if (!(name = get_clnt_name(rqstp))) { 149*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 150*0Sstevel@tonic-gate gettext("%s: Couldn't obtain client's name"), 151*0Sstevel@tonic-gate whoami); 152*0Sstevel@tonic-gate goto out; 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate if (!acl_check(handle->context, 155*0Sstevel@tonic-gate name, 156*0Sstevel@tonic-gate ACL_IPROP, 157*0Sstevel@tonic-gate NULL, 158*0Sstevel@tonic-gate NULL)) { 159*0Sstevel@tonic-gate ret.ret = UPDATE_PERM_DENIED; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate audit_kadmind_unauth(rqstp->rq_xprt, l_port, 162*0Sstevel@tonic-gate whoami, 163*0Sstevel@tonic-gate "<null>", client_name); 164*0Sstevel@tonic-gate krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, whoami, 165*0Sstevel@tonic-gate "<null>", client_name, service_name, 166*0Sstevel@tonic-gate client_addr(rqstp, abuf)); 167*0Sstevel@tonic-gate goto out; 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate kret = ulog_get_entries(handle->context, *arg, &ret); 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate if (ret.ret == UPDATE_OK) { 173*0Sstevel@tonic-gate (void) snprintf(obuf, sizeof (obuf), 174*0Sstevel@tonic-gate gettext("%s; Incoming SerialNo=%u; Outgoing SerialNo=%u"), 175*0Sstevel@tonic-gate replystr(ret.ret), 176*0Sstevel@tonic-gate (ulong_t)arg->last_sno, 177*0Sstevel@tonic-gate (ulong_t)ret.lastentry.last_sno); 178*0Sstevel@tonic-gate } else { 179*0Sstevel@tonic-gate (void) snprintf(obuf, sizeof (obuf), 180*0Sstevel@tonic-gate gettext("%s; Incoming SerialNo=%u; Outgoing SerialNo=N/A"), 181*0Sstevel@tonic-gate replystr(ret.ret), 182*0Sstevel@tonic-gate (ulong_t)arg->last_sno); 183*0Sstevel@tonic-gate } 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate audit_kadmind_auth(rqstp->rq_xprt, l_port, 186*0Sstevel@tonic-gate whoami, 187*0Sstevel@tonic-gate obuf, client_name, kret); 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate krb5_klog_syslog(LOG_NOTICE, LOG_DONE, whoami, 190*0Sstevel@tonic-gate obuf, 191*0Sstevel@tonic-gate ((kret == 0) ? "success" : error_message(kret)), 192*0Sstevel@tonic-gate client_name, service_name, 193*0Sstevel@tonic-gate client_addr(rqstp, abuf)); 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate out: 196*0Sstevel@tonic-gate if (nofork) 197*0Sstevel@tonic-gate debprret(whoami, ret.ret, ret.lastentry.last_sno); 198*0Sstevel@tonic-gate if (client_name) 199*0Sstevel@tonic-gate free(client_name); 200*0Sstevel@tonic-gate if (service_name) 201*0Sstevel@tonic-gate free(service_name); 202*0Sstevel@tonic-gate if (name) 203*0Sstevel@tonic-gate gss_release_name(&min_stat, &name); 204*0Sstevel@tonic-gate return (&ret); 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate /* 209*0Sstevel@tonic-gate * Given a client princ (foo/fqdn@R), copy (in arg cl) the fqdn substring. 210*0Sstevel@tonic-gate * Return arg cl str ptr on success, else NULL. 211*0Sstevel@tonic-gate */ 212*0Sstevel@tonic-gate static char * 213*0Sstevel@tonic-gate getclhoststr(char *clprinc, char *cl, int len) 214*0Sstevel@tonic-gate { 215*0Sstevel@tonic-gate char *s; 216*0Sstevel@tonic-gate if (s = strchr(clprinc, '/')) { 217*0Sstevel@tonic-gate if (!++s || strlcpy(cl, s, len) >= len) { 218*0Sstevel@tonic-gate return (NULL); 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate if (s = strchr(cl, '@')) { 221*0Sstevel@tonic-gate *s = '\0'; 222*0Sstevel@tonic-gate return (cl); /* success */ 223*0Sstevel@tonic-gate } 224*0Sstevel@tonic-gate } 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate return (NULL); 227*0Sstevel@tonic-gate } 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate kdb_fullresync_result_t * 230*0Sstevel@tonic-gate iprop_full_resync_1( 231*0Sstevel@tonic-gate /* LINTED */ 232*0Sstevel@tonic-gate void *argp, 233*0Sstevel@tonic-gate struct svc_req *rqstp) 234*0Sstevel@tonic-gate { 235*0Sstevel@tonic-gate static kdb_fullresync_result_t ret; 236*0Sstevel@tonic-gate char tmpf[MAX_FILENAME] = {0}; 237*0Sstevel@tonic-gate char ubuf[MAX_FILENAME + sizeof (KDB5_UTIL_DUMP_STR)] = {0}; 238*0Sstevel@tonic-gate char clhost[MAXHOSTNAMELEN] = {0}; 239*0Sstevel@tonic-gate int pret, fret; 240*0Sstevel@tonic-gate kadm5_server_handle_t handle = global_server_handle; 241*0Sstevel@tonic-gate OM_uint32 min_stat; 242*0Sstevel@tonic-gate gss_name_t name = NULL; 243*0Sstevel@tonic-gate char *client_name = NULL, *service_name = NULL; 244*0Sstevel@tonic-gate char *whoami = "iprop_full_resync_1"; 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate /* default return code */ 247*0Sstevel@tonic-gate ret.ret = UPDATE_ERROR; 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate if (!handle) { 250*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 251*0Sstevel@tonic-gate gettext("%s: server handle is NULL"), 252*0Sstevel@tonic-gate whoami); 253*0Sstevel@tonic-gate goto out; 254*0Sstevel@tonic-gate } 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate DPRINT(("%s: start\n", whoami)); 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 259*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 260*0Sstevel@tonic-gate gettext("%s: setup_gss_names failed"), 261*0Sstevel@tonic-gate whoami); 262*0Sstevel@tonic-gate goto out; 263*0Sstevel@tonic-gate } 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate DPRINT(("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n", 266*0Sstevel@tonic-gate whoami, client_name, service_name)); 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate if (!(name = get_clnt_name(rqstp))) { 269*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 270*0Sstevel@tonic-gate gettext("%s: Couldn't obtain client's name"), 271*0Sstevel@tonic-gate whoami); 272*0Sstevel@tonic-gate goto out; 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate if (!acl_check(handle->context, 275*0Sstevel@tonic-gate name, 276*0Sstevel@tonic-gate ACL_IPROP, 277*0Sstevel@tonic-gate NULL, 278*0Sstevel@tonic-gate NULL)) { 279*0Sstevel@tonic-gate ret.ret = UPDATE_PERM_DENIED; 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gate audit_kadmind_unauth(rqstp->rq_xprt, l_port, 282*0Sstevel@tonic-gate whoami, 283*0Sstevel@tonic-gate "<null>", client_name); 284*0Sstevel@tonic-gate krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, whoami, 285*0Sstevel@tonic-gate "<null>", client_name, service_name, 286*0Sstevel@tonic-gate client_addr(rqstp, abuf)); 287*0Sstevel@tonic-gate goto out; 288*0Sstevel@tonic-gate } 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate if (!getclhoststr(client_name, clhost, sizeof (clhost))) { 291*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 292*0Sstevel@tonic-gate gettext("%s: getclhoststr failed"), 293*0Sstevel@tonic-gate whoami); 294*0Sstevel@tonic-gate goto out; 295*0Sstevel@tonic-gate } 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate /* 298*0Sstevel@tonic-gate * construct db dump file name; kprop style name + clnt fqdn 299*0Sstevel@tonic-gate */ 300*0Sstevel@tonic-gate (void) strcpy(tmpf, "/var/krb5/slave_datatrans_"); 301*0Sstevel@tonic-gate if (strlcat(tmpf, clhost, sizeof (tmpf)) >= sizeof (tmpf)) { 302*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 303*0Sstevel@tonic-gate gettext("%s: db dump file name too long; max length=%d"), 304*0Sstevel@tonic-gate whoami, 305*0Sstevel@tonic-gate (sizeof (tmpf) - 1)); 306*0Sstevel@tonic-gate goto out; 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate /* 310*0Sstevel@tonic-gate * note the -i; modified version of kdb5_util dump format 311*0Sstevel@tonic-gate * to include sno (serial number) 312*0Sstevel@tonic-gate */ 313*0Sstevel@tonic-gate if (strlcpy(ubuf, KDB5_UTIL_DUMP_STR, sizeof (ubuf)) >= 314*0Sstevel@tonic-gate sizeof (ubuf)) { 315*0Sstevel@tonic-gate goto out; 316*0Sstevel@tonic-gate } 317*0Sstevel@tonic-gate if (strlcat(ubuf, tmpf, sizeof (ubuf)) >= sizeof (ubuf)) { 318*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 319*0Sstevel@tonic-gate gettext("%s: kdb5 util dump string too long; max length=%d"), 320*0Sstevel@tonic-gate whoami, 321*0Sstevel@tonic-gate (sizeof (ubuf) - 1)); 322*0Sstevel@tonic-gate goto out; 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate /* 326*0Sstevel@tonic-gate * Fork to dump the db and xfer it to the slave. 327*0Sstevel@tonic-gate * (the fork allows parent to return quickly and the child 328*0Sstevel@tonic-gate * acts like a callback to the slave). 329*0Sstevel@tonic-gate */ 330*0Sstevel@tonic-gate fret = fork(); 331*0Sstevel@tonic-gate DPRINT(("%s: fork=%d (%d)\n", whoami, fret, getpid())); 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate switch (fret) { 334*0Sstevel@tonic-gate case -1: /* error */ 335*0Sstevel@tonic-gate if (nofork) { 336*0Sstevel@tonic-gate perror(whoami); 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 339*0Sstevel@tonic-gate gettext("%s: fork failed: %s"), 340*0Sstevel@tonic-gate whoami, 341*0Sstevel@tonic-gate error_message(errno)); 342*0Sstevel@tonic-gate goto out; 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate case 0: /* child */ 345*0Sstevel@tonic-gate DPRINT(("%s: run `%s' ...\n", whoami, ubuf)); 346*0Sstevel@tonic-gate (void) signal(SIGCHLD, SIG_DFL); 347*0Sstevel@tonic-gate /* run kdb5_util(1M) dump for IProp */ 348*0Sstevel@tonic-gate pret = pclose(popen(ubuf, "w")); 349*0Sstevel@tonic-gate DPRINT(("%s: pclose=%d\n", whoami, pret)); 350*0Sstevel@tonic-gate if (pret == -1) { 351*0Sstevel@tonic-gate if (nofork) { 352*0Sstevel@tonic-gate perror(whoami); 353*0Sstevel@tonic-gate } 354*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 355*0Sstevel@tonic-gate gettext("%s: pclose(popen) failed: %s"), 356*0Sstevel@tonic-gate whoami, 357*0Sstevel@tonic-gate error_message(errno)); 358*0Sstevel@tonic-gate goto out; 359*0Sstevel@tonic-gate } 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate DPRINT(("%s: exec `kprop -f %s %s' ...\n", 362*0Sstevel@tonic-gate whoami, tmpf, clhost)); 363*0Sstevel@tonic-gate pret = execl("/usr/lib/krb5/kprop", "kprop", "-f", tmpf, 364*0Sstevel@tonic-gate clhost, NULL); 365*0Sstevel@tonic-gate if (pret == -1) { 366*0Sstevel@tonic-gate if (nofork) { 367*0Sstevel@tonic-gate perror(whoami); 368*0Sstevel@tonic-gate } 369*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 370*0Sstevel@tonic-gate gettext("%s: exec failed: %s"), 371*0Sstevel@tonic-gate whoami, 372*0Sstevel@tonic-gate error_message(errno)); 373*0Sstevel@tonic-gate goto out; 374*0Sstevel@tonic-gate } 375*0Sstevel@tonic-gate 376*0Sstevel@tonic-gate default: /* parent */ 377*0Sstevel@tonic-gate ret.ret = UPDATE_OK; 378*0Sstevel@tonic-gate /* not used by slave (sno is retrieved from kdb5_util dump) */ 379*0Sstevel@tonic-gate ret.lastentry.last_sno = 0; 380*0Sstevel@tonic-gate ret.lastentry.last_time.seconds = 0; 381*0Sstevel@tonic-gate ret.lastentry.last_time.useconds = 0; 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate audit_kadmind_auth(rqstp->rq_xprt, l_port, 384*0Sstevel@tonic-gate whoami, 385*0Sstevel@tonic-gate "<null>", client_name, 0); 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate krb5_klog_syslog(LOG_NOTICE, LOG_DONE, whoami, 388*0Sstevel@tonic-gate "<null>", 389*0Sstevel@tonic-gate "success", 390*0Sstevel@tonic-gate client_name, service_name, 391*0Sstevel@tonic-gate client_addr(rqstp, abuf)); 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate goto out; 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate out: 397*0Sstevel@tonic-gate if (nofork) 398*0Sstevel@tonic-gate debprret(whoami, ret.ret, 0); 399*0Sstevel@tonic-gate if (client_name) 400*0Sstevel@tonic-gate free(client_name); 401*0Sstevel@tonic-gate if (service_name) 402*0Sstevel@tonic-gate free(service_name); 403*0Sstevel@tonic-gate if (name) 404*0Sstevel@tonic-gate gss_release_name(&min_stat, &name); 405*0Sstevel@tonic-gate return (&ret); 406*0Sstevel@tonic-gate } 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate void 409*0Sstevel@tonic-gate krb5_iprop_prog_1( 410*0Sstevel@tonic-gate struct svc_req *rqstp, 411*0Sstevel@tonic-gate register SVCXPRT *transp) 412*0Sstevel@tonic-gate { 413*0Sstevel@tonic-gate union { 414*0Sstevel@tonic-gate kdb_last_t iprop_get_updates_1_arg; 415*0Sstevel@tonic-gate } argument; 416*0Sstevel@tonic-gate char *result; 417*0Sstevel@tonic-gate bool_t (*_xdr_argument)(), (*_xdr_result)(); 418*0Sstevel@tonic-gate char *(*local)(); 419*0Sstevel@tonic-gate char *whoami = "krb5_iprop_prog_1"; 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate switch (rqstp->rq_proc) { 422*0Sstevel@tonic-gate case NULLPROC: 423*0Sstevel@tonic-gate (void) svc_sendreply(transp, xdr_void, 424*0Sstevel@tonic-gate (char *)NULL); 425*0Sstevel@tonic-gate return; 426*0Sstevel@tonic-gate 427*0Sstevel@tonic-gate case IPROP_GET_UPDATES: 428*0Sstevel@tonic-gate _xdr_argument = xdr_kdb_last_t; 429*0Sstevel@tonic-gate _xdr_result = xdr_kdb_incr_result_t; 430*0Sstevel@tonic-gate local = (char *(*)()) iprop_get_updates_1; 431*0Sstevel@tonic-gate break; 432*0Sstevel@tonic-gate 433*0Sstevel@tonic-gate case IPROP_FULL_RESYNC: 434*0Sstevel@tonic-gate _xdr_argument = xdr_void; 435*0Sstevel@tonic-gate _xdr_result = xdr_kdb_fullresync_result_t; 436*0Sstevel@tonic-gate local = (char *(*)()) iprop_full_resync_1; 437*0Sstevel@tonic-gate break; 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate default: 440*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 441*0Sstevel@tonic-gate gettext("RPC unknown request: %d (%s)"), 442*0Sstevel@tonic-gate rqstp->rq_proc, whoami); 443*0Sstevel@tonic-gate svcerr_noproc(transp); 444*0Sstevel@tonic-gate return; 445*0Sstevel@tonic-gate } 446*0Sstevel@tonic-gate (void) memset((char *)&argument, 0, sizeof (argument)); 447*0Sstevel@tonic-gate if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) { 448*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 449*0Sstevel@tonic-gate gettext("RPC svc_getargs failed (%s)"), 450*0Sstevel@tonic-gate whoami); 451*0Sstevel@tonic-gate svcerr_decode(transp); 452*0Sstevel@tonic-gate return; 453*0Sstevel@tonic-gate } 454*0Sstevel@tonic-gate result = (*local)(&argument, rqstp); 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate if (_xdr_result && result != NULL && 457*0Sstevel@tonic-gate !svc_sendreply(transp, _xdr_result, result)) { 458*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 459*0Sstevel@tonic-gate gettext("RPC svc_sendreply failed (%s)"), 460*0Sstevel@tonic-gate whoami); 461*0Sstevel@tonic-gate svcerr_systemerr(transp); 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate if (!svc_freeargs(transp, _xdr_argument, (caddr_t)&argument)) { 464*0Sstevel@tonic-gate krb5_klog_syslog(LOG_ERR, 465*0Sstevel@tonic-gate gettext("RPC svc_freeargs failed (%s)"), 466*0Sstevel@tonic-gate whoami); 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate exit(1); 469*0Sstevel@tonic-gate } 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate if (rqstp->rq_proc == IPROP_GET_UPDATES) { 472*0Sstevel@tonic-gate /* LINTED */ 473*0Sstevel@tonic-gate kdb_incr_result_t *r = (kdb_incr_result_t *)result; 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate if (r->ret == UPDATE_OK) { 476*0Sstevel@tonic-gate ulog_free_entries(r->updates.kdb_ulog_t_val, 477*0Sstevel@tonic-gate r->updates.kdb_ulog_t_len); 478*0Sstevel@tonic-gate r->updates.kdb_ulog_t_val = NULL; 479*0Sstevel@tonic-gate r->updates.kdb_ulog_t_len = 0; 480*0Sstevel@tonic-gate } 481*0Sstevel@tonic-gate } 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gate /* 486*0Sstevel@tonic-gate * Get the host base service name for the kiprop principal. Returns 487*0Sstevel@tonic-gate * KADM5_OK on success. Caller must free the storage allocated for 488*0Sstevel@tonic-gate * host_service_name. 489*0Sstevel@tonic-gate */ 490*0Sstevel@tonic-gate kadm5_ret_t 491*0Sstevel@tonic-gate kiprop_get_adm_host_srv_name( 492*0Sstevel@tonic-gate krb5_context context, 493*0Sstevel@tonic-gate const char *realm, 494*0Sstevel@tonic-gate char **host_service_name) 495*0Sstevel@tonic-gate { 496*0Sstevel@tonic-gate kadm5_ret_t ret; 497*0Sstevel@tonic-gate char *name; 498*0Sstevel@tonic-gate char *host; 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate if (ret = kadm5_get_master(context, realm, &host)) 501*0Sstevel@tonic-gate return (ret); 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate name = malloc(strlen(KIPROP_SVC_NAME)+ strlen(host) + 2); 504*0Sstevel@tonic-gate if (name == NULL) { 505*0Sstevel@tonic-gate free(host); 506*0Sstevel@tonic-gate return (ENOMEM); 507*0Sstevel@tonic-gate } 508*0Sstevel@tonic-gate (void) sprintf(name, "%s@%s", KIPROP_SVC_NAME, host); 509*0Sstevel@tonic-gate free(host); 510*0Sstevel@tonic-gate *host_service_name = name; 511*0Sstevel@tonic-gate 512*0Sstevel@tonic-gate return (KADM5_OK); 513*0Sstevel@tonic-gate } 514