#include <netinet/in.h>
#include <netdb.h>
#include <des.h>
+#include <krb.h>
+#include <krb_err.h>
#include <errno.h>
#include <moira.h>
#include <moira_site.h>
#include "ureg_err.h"
#include "ureg_proto.h"
#include <strings.h>
+#include <ctype.h>
static int reg_sock = -1;
static int seq_no = 0;
+static char *host;
extern errno;
#define UNKNOWN_HOST -1
#define UNKNOWN_SERVICE -2
ureg_init()
{
struct servent *sp;
- char *host, **p, *s;
+ char **p, *s;
struct hostent *hp;
struct sockaddr_in sin;
extern char *getenv(), **hes_resolve();
UREG_GET_KRB));
}
+
+/* The handles the operations for secure passwords.
+ * To find out if a user has a secure instance, only the login name
+ * and the opcode = UREG_GET_SECURE need to be specified (but the
+ * other strings must be valid char*'s). This will return
+ * UREG_ALREADY_REGISTERED if it is set, or SUCCESS if not.
+ * To set the password, fill in the rest of the fields, and
+ * use opcode = UREG_SET_SECURE. This returns SUCCESS or any number
+ * of failure codes.
+ */
+
+do_secure_operation(login, idnumber, passwd, newpasswd, opcode)
+ char *login, *idnumber, *passwd, *newpasswd;
+ u_long opcode;
+{
+ char buf[1500], data[128], tktstring[128];
+ int version = ntohl((u_long)1);
+ int call = ntohl(opcode);
+ char inst[INST_SZ], hosti[INST_SZ];
+ char *bp = buf, *src, *dst, *realm;
+ int len, status, i;
+ KTEXT_ST cred;
+ CREDENTIALS creds;
+ Key_schedule keys;
+ char *krb_get_phost(), *krb_realmofhost();
+
+ bcopy((char *)&version, bp, sizeof(int));
+ bp += sizeof(int);
+ seq_no++;
+ bcopy((char *)&seq_no, bp, sizeof(int));
+
+ bp += sizeof(int);
+
+ bcopy((char *)&call, bp, sizeof(int));
+
+ bp += sizeof(int);
+
+ /* put the login name in the firstname field */
+ (void) strcpy(bp, login);
+ bp += strlen(bp)+1;
+
+ /* the old lastname field */
+ (void) strcpy(bp, "");
+ bp += strlen(bp)+1;
+
+ /* don't overwrite existing ticket file */
+ (void) sprintf(tktstring, "/tmp/tkt_cpw_%d",getpid());
+ krb_set_tkt_string(tktstring);
+
+ /* get realm and canonizalized hostname of server */
+ realm = krb_realmofhost(host);
+ for (src = host, dst = hosti; *src && *src != '.'; src++)
+ if (isupper(*src))
+ *dst++ = tolower(*src);
+ else
+ *dst++ = *src;
+ *dst = 0;
+ inst[0] = 0;
+ inst[0] = 0;
+
+ /* get changepw tickets. We use this service because it's the
+ * only one that guarantees we used the password rather than a
+ * ticket granting ticket.
+ */
+ status = krb_get_pw_in_tkt(login, inst, realm,
+ "changepw", hosti, 5, passwd);
+ bzero(passwd, strlen(passwd));
+ if (status) {
+ bzero(newpasswd, strlen(newpasswd));
+ return (status + krb_err_base);
+ }
+
+ status = krb_mk_req(&cred, "changepw", hosti, realm, 0);
+ if (status) {
+ bzero(newpasswd, strlen(newpasswd));
+ return (status + krb_err_base);
+ }
+
+ /* round up to word boundry */
+ bp = (char *)((((u_long)bp)+3)&0xfffffffc);
+
+ /* put the ticket in the packet */
+ len = cred.length;
+ cred.length = htonl(cred.length);
+ bcopy(&(cred), bp, sizeof(int)+len);
+#ifdef DEBUG
+ com_err("test", 0, "Cred: length %d", len);
+ for (i = 0; i < len; i += 16)
+ com_err("test", 0, " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ cred.dat[i+0], cred.dat[i+1], cred.dat[i+2], cred.dat[i+3],
+ cred.dat[i+4], cred.dat[i+5], cred.dat[i+6], cred.dat[i+7],
+ cred.dat[i+8], cred.dat[i+9], cred.dat[i+10], cred.dat[i+11],
+ cred.dat[i+12], cred.dat[i+13], cred.dat[i+14], cred.dat[i+15]);
+#endif /* DEBUG */
+ bp += sizeof(int) + len;
+
+ /* encrypt the data in the session key */
+ sprintf(data, "%s,%s", idnumber, newpasswd);
+ len = strlen(data);
+ len = ((len + 7) >> 3) << 3;
+
+ status = krb_get_cred("changepw", hosti, realm, &creds);
+ if (status) {
+ bzero(newpasswd, strlen(newpasswd));
+ bzero(data, strlen(data));
+ return (status + krb_err_base);
+ }
+ dest_tkt();
+
+ des_key_sched(creds.session, keys);
+ des_pcbc_encrypt(data, bp + sizeof(int), len, keys, creds.session, 1);
+ *((int *)bp) = htonl(len);
+ bzero(data, strlen(data));
+
+ bp += len + sizeof(int);
+
+ len = bp - buf;
+ return do_call(buf, len, seq_no, 0);
+
+}
+
static do_call(buf, len, seq_no, login)
char *buf;
char *login;