Print this page
6817447 libgss and various mechs are hiding both the real minor_status and the error token
6405422 Solaris acceptors fail in AD-KDC environments when using non-"host" services (e.g. "cifs")
6824434 Unable to accept context establishment initiated by Windows 2000 clients
6787343 kclient's site lookups fail in certain network environments
6692646 kclient should output errors to stderr
6525327 kinit failed when arcfour-hmac-md5-exp was used for the principal's key
6745582 SUNWkdcu missing package dependencies after kclientv2 integration
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/krb5/kadmin/kclient/kclient.sh
+++ new/usr/src/cmd/krb5/kadmin/kclient/kclient.sh
1 1 #!/bin/ksh93 -p
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 # and limitations under the License.
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 -# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
22 +# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 # Use is subject to license terms.
24 24 #
25 25 # This script is used to setup the Kerberos client by
26 26 # supplying information about the Kerberos realm and kdc.
27 27 #
28 28 # The kerberos configuration file (/etc/krb5/krb5.conf) would
29 29 # be generated and local host's keytab file setup. The script
30 30 # can also optionally setup the system to do kerberized nfs and
31 31 # bringover a master krb5.conf copy from a specified location.
32 32
33 33 function cleanup {
34 - integer ret=$1
35 34
36 - kdestroy -q 1> $TMP_FILE 2>&1
35 + kdestroy -q > $TMP_FILE 2>&1
37 36 rm -r $TMPDIR > /dev/null 2>&1
38 37
39 - exit $ret
38 + exit $1
40 39 }
41 40 function exiting {
42 41
43 42 printf "\n$(gettext "Exiting setup, nothing changed").\n\n"
44 43
45 44 cleanup $1
46 45 }
47 46
48 47 function error_message {
49 48
50 - printf -- "---------------------------------------------------\n"
51 - printf "$(gettext "Setup FAILED").\n\n"
49 + printf -- "---------------------------------------------------\n" >&2
50 + printf "$(gettext "Setup FAILED").\n\n" >&2
52 51
53 52 cleanup 1
54 53 }
55 54
56 55 function check_bin {
57 56
58 57 typeset bin=$1
59 58
60 59 if [[ ! -x $bin ]]; then
61 - printf "$(gettext "Could not access/execute %s").\n" $bin
60 + printf "$(gettext "Could not access/execute %s").\n" $bin >&2
62 61 error_message
63 62 fi
64 63 }
65 64
66 65 function cannot_create {
67 66 typeset filename="$1"
68 67 typeset stat="$2"
69 68
70 69 if [[ $stat -ne 0 ]]; then
71 70 printf "\n$(gettext "Can not create/edit %s, exiting").\n" $filename >&2
72 71 error_message
73 72 fi
74 73 }
75 74
76 75 function update_pam_conf {
77 76 typeset PAM TPAM service
78 77
79 78 PAM=/etc/pam.conf
80 79
81 80 TPAM=$(mktemp -q -t kclient-pamconf.XXXXXX)
82 81 if [[ -z $TPAM ]]; then
83 82 printf "\n$(gettext "Can not create temporary file, exiting").\n" >&2
84 83 error_message
85 84 fi
86 85
87 86 cp $PAM $TPAM >/dev/null 2>&1
88 87
89 88 printf "$(gettext "Configuring %s").\n\n" $PAM
90 89
91 90 for service in $SVCs; do
92 91 svc=${service%:*}
93 92 auth_type=${service#*:}
94 93 if egrep -s "^$svc[ ][ ]*auth.*pam_krb5*" $TPAM; then
95 94 printf "$(gettext "The %s service is already configured for pam_krb5, please merge this service in %s").\n\n" $svc $PAM >&2
96 95 continue
97 96 else
98 97 exec 3>>$TPAM
99 98 printf "\n$svc\tauth include\t\tpam_krb5_$auth_type\n" 1>&3
100 99 fi
101 100 done
102 101
103 102 cp $TPAM $PAM > /dev/null 2>&1
104 103
105 104 rm $TPAM > /dev/null 2>&1
106 105 }
107 106
108 107 function modify_nfssec_conf {
109 108 typeset NFSSEC_FILE="/etc/nfssec.conf"
110 109
111 110 if [[ -r $NFSSEC_FILE ]]; then
112 111 cat $NFSSEC_FILE > $NFSSEC_FILE.sav
113 112 cannot_create $NFSSEC_FILE.sav $?
114 113 fi
115 114
116 115 cat $NFSSEC_FILE > $TMP_FILE
117 116 cannot_create $TMP_FILE $?
118 117
119 118 if grep -s "#krb5" $NFSSEC_FILE > /dev/null 2>&1; then
120 119 sed "s%^#krb5%krb5%" $TMP_FILE >$NFSSEC_FILE
121 120 cannot_create $NFSSEC_FILE $?
122 121 fi
123 122 }
124 123
125 124 function call_kadmin {
126 125 typeset svc="$1"
127 126 typeset bool1 bool2 bool3 bool4
128 127 typeset service_princ getprincsubcommand anksubcommand ktaddsubcommand
129 128 typeset ktremsubcommand
130 129
131 130 for listentry in $fqdnlist; do
132 131
133 132 # Reset conditional vars to 1
134 133 bool1=1; bool2=1; bool3=1; bool4=1
135 134
136 135 service_princ=$(echo "${svc}/${listentry}")
137 136 getprincsubcommand="getprinc $service_princ"
138 137 anksubcommand="addprinc -randkey $service_princ"
139 138 ktaddsubcommand="ktadd $service_princ"
140 139 ktremsubcommand="ktrem $service_princ all"
141 140
142 141 kadmin -c $KRB5CCNAME -q "$getprincsubcommand" 1>$TMP_FILE 2>&1
143 142
144 143 egrep -s "$(gettext "get_principal: Principal does not exist")" $TMP_FILE
145 144 bool1=$?
146 145 egrep -s "$(gettext "get_principal: Operation requires ``get")" $TMP_FILE
147 146 bool2=$?
148 147
149 148 if [[ $bool1 -eq 0 || $bool2 -eq 0 ]]; then
150 149 kadmin -c $KRB5CCNAME -q "$anksubcommand" 1>$TMP_FILE 2>&1
151 150
152 151 egrep -s "$(gettext "add_principal: Principal or policy already exists while creating \"$service_princ@$realm\".")" $TMP_FILE
153 152 bool3=$?
154 153
155 154 egrep -s "$(gettext "Principal \"$service_princ@$realm\" created.")" $TMP_FILE
156 155 bool4=$?
157 156
158 157 if [[ $bool3 -eq 0 || $bool4 -eq 0 ]]; then
159 158 printf "$(gettext "%s entry ADDED to KDC database").\n" $service_princ
160 159 else
161 160 cat $TMP_FILE;
162 161 printf "\n$(gettext "kadmin: add_principal of %s failed, exiting").\n" $service_princ >&2
163 162 error_message
164 163 fi
165 164 else
166 165 printf "$(gettext "%s entry already exists in KDC database").\n" $service_princ >&2
167 166 fi
168 167
169 168 klist -k 1>$TMP_FILE 2>&1
170 169 egrep -s "$service_princ@$realm" $TMP_FILE
171 170 if [[ $? -eq 0 ]]; then
172 171 printf "$(gettext "%s entry already present in keytab").\n" $service_princ >&2
173 172 # Don't care is this succeeds or not, just need to replace old
174 173 # entries as it is assummed that the client is reinitialized
175 174 kadmin -c $KRB5CCNAME -q "$ktremsubcommand" 1>$TMP_FILE 2>&1
176 175 fi
177 176
178 177 kadmin -c $KRB5CCNAME -q "$ktaddsubcommand" 1>$TMP_FILE 2>&1
179 178 egrep -s "$(gettext "added to keytab WRFILE:$KRB5_KEYTAB_FILE.")" $TMP_FILE
180 179 if [[ $? -ne 0 ]]; then
181 180 cat $TMP_FILE;
182 181 printf "\n$(gettext "kadmin: ktadd of %s failed, exiting").\n" $service_princ >&2
183 182 error_message
184 183 else
185 184 printf "$(gettext "%s entry ADDED to keytab").\n" $service_princ
186 185 fi
187 186
|
↓ open down ↓ |
116 lines elided |
↑ open up ↑ |
188 187 done
189 188 }
190 189
191 190 function writeup_krb5_conf {
192 191 typeset dh
193 192
194 193 printf "\n$(gettext "Setting up %s").\n\n" $KRB5_CONFIG_FILE
195 194
196 195 exec 3>$KRB5_CONFIG
197 196 if [[ $? -ne 0 ]]; then
198 - printf "\n$(gettext "Can not write to %s, exiting").\n" $KRB5_CONFIG
197 + printf "\n$(gettext "Can not write to %s, exiting").\n" $KRB5_CONFIG >&2
199 198 error_message
200 199 fi
201 200
202 201 printf "[libdefaults]\n" 1>&3
203 202 if [[ $no_keytab == yes ]]; then
204 203 printf "\tverify_ap_req_nofail = false\n" 1>&3
205 204 fi
206 205 if [[ $dns_lookup == yes ]]; then
207 206 printf "\t$dnsarg = on\n" 1>&3
208 207 if [[ $dnsarg == dns_lookup_kdc ]]; then
209 208 printf "\tdefault_realm = $realm\n" 1>&3
210 209 printf "\n[domain_realm]\n" 1>&3
211 210 if [[ -n $fkdc_list ]]; then
212 211 for kdc in $fkdc_list; do
213 212 printf "\t$kdc = $realm\n" 1>&3
214 213 done
215 214 fi
216 215 printf "\t$FKDC = $realm\n" 1>&3
217 216 printf "\t$client_machine = $realm\n" 1>&3
218 217 if [[ -z $short_fqdn ]]; then
219 218 printf "\t.$domain = $realm\n\n" 1>&3
220 219 else
221 220 printf "\t.$short_fqdn = $realm\n\n" 1>&3
222 221 fi
223 222 if [[ -n $domain_list ]]; then
224 223 for dh in $domain_list; do
225 224 printf "\t$dh = $realm\n" 1>&3
226 225 done
227 226 fi
228 227 else
229 228 if [[ $dnsarg = dns_lookup_realm ]]; then
230 229 printf "\tdefault_realm = $realm\n" 1>&3
231 230 printf "\n[realms]\n" 1>&3
232 231 printf "\t$realm = {\n" 1>&3
233 232 if [[ -n $kdc_list ]]; then
234 233 for kdc in $kdc_list; do
235 234 printf "\t\tkdc = $kdc\n" 1>&3
236 235 done
237 236 else
238 237 printf "\t\tkdc = $KDC\n" 1>&3
239 238 fi
240 239 printf "\t\tadmin_server = $KDC\n" 1>&3
241 240 if [[ $non_solaris == yes ]]; then
242 241 printf "\n\t\tkpasswd_protocol = SET_CHANGE\n" 1>&3
243 242 fi
244 243 printf "\t}\n\n" 1>&3
245 244 else
246 245 printf "\tdefault_realm = $realm\n\n" 1>&3
247 246 fi
248 247 fi
249 248 else
250 249 printf "\tdefault_realm = $realm\n\n" 1>&3
251 250
252 251 printf "[realms]\n" 1>&3
253 252 printf "\t$realm = {\n" 1>&3
254 253 if [[ -n $kdc_list ]]; then
255 254 for kdc in $kdc_list; do
256 255 printf "\t\tkdc = $kdc\n" 1>&3
257 256 done
258 257 else
259 258 printf "\t\tkdc = $KDC\n" 1>&3
260 259 fi
261 260 printf "\t\tadmin_server = $KDC\n" 1>&3
262 261 if [[ $non_solaris == yes ]]; then
263 262 printf "\n\t\tkpasswd_protocol = SET_CHANGE\n" 1>&3
264 263 fi
265 264 printf "\t}\n\n" 1>&3
266 265
267 266 printf "[domain_realm]\n" 1>&3
268 267 if [[ -n $fkdc_list ]]; then
269 268 for kdc in $fkdc_list; do
270 269 printf "\t$kdc = $realm\n" 1>&3
271 270 done
272 271 fi
273 272 printf "\t$FKDC = $realm\n" 1>&3
274 273 printf "\t$client_machine = $realm\n" 1>&3
275 274 if [[ -z $short_fqdn ]]; then
276 275 printf "\t.$domain = $realm\n\n" 1>&3
277 276 else
278 277 printf "\t.$short_fqdn = $realm\n\n" 1>&3
279 278 fi
280 279 if [[ -n $domain_list ]]; then
281 280 for dh in $domain_list; do
282 281 printf "\t$dh = $realm\n" 1>&3
283 282 done
284 283 fi
285 284 fi
286 285
287 286 printf "[logging]\n" 1>&3
288 287 printf "\tdefault = FILE:/var/krb5/kdc.log\n" 1>&3
289 288 printf "\tkdc = FILE:/var/krb5/kdc.log\n" 1>&3
290 289 printf "\tkdc_rotate = {\n\t\tperiod = 1d\n\t\tversions = 10\n\t}\n\n" 1>&3
291 290
292 291 printf "[appdefaults]\n" 1>&3
293 292 printf "\tkinit = {\n\t\trenewable = true\n\t\tforwardable = true\n" 1>&3
294 293 if [[ $no_keytab == yes ]]; then
295 294 printf "\t\tno_addresses = true\n" 1>&3
296 295 fi
297 296 printf "\t}\n" 1>&3
298 297 }
299 298
300 299 function ask {
301 300 typeset question=$1
302 301 typeset default_answer=$2
303 302
304 303 if [[ -z $default_answer ]]; then
305 304 printf "$question :"
306 305 else
307 306 printf "$question [$default_answer]: "
308 307 fi
309 308 read answer
310 309 test -z "$answer" && answer="$default_answer"
311 310 }
312 311
313 312 function yesno {
314 313 typeset question="$1"
315 314
316 315 answer=
317 316 yn=`printf "$(gettext "y/n")"`
318 317 y=`printf "$(gettext "y")"`
319 318 n=`printf "$(gettext "n")"`
320 319 yes=`printf "$(gettext "yes")"`
321 320 no=`printf "$(gettext "no")"`
322 321
323 322 while [[ -z $answer ]]; do
324 323 ask "$question" $yn
325 324 case $answer in
326 325 $y|$yes) answer=yes;;
327 326 $n|$no) answer=no;;
328 327 *) answer=;;
329 328 esac
330 329 done
331 330 }
332 331
333 332 function query {
334 333 yesno "$*"
335 334
336 335 if [[ $answer == no ]]; then
337 336 printf "\t$(gettext "No action performed").\n"
338 337 fi
339 338 }
340 339
341 340
342 341 function read_profile {
343 342 typeset param value
344 343 typeset file="$1"
345 344
346 345 if [[ ! -d $file && -r $file ]]; then
347 346 while read param value
348 347 do
349 348 case $param in
350 349 REALM) if [[ -z $realm ]]; then
351 350 realm="$value"
352 351 checkval="REALM"; check_value $realm
353 352 fi
354 353 ;;
355 354 KDC) if [[ -z $KDC ]]; then
356 355 KDC="$value"
357 356 checkval="KDC"; check_value $KDC
358 357 fi
359 358 ;;
360 359 ADMIN) if [[ -z $ADMIN_PRINC ]]; then
361 360 ADMIN_PRINC="$value"
362 361 checkval="ADMIN_PRINC"
363 362 check_value $ADMIN_PRINC
364 363 fi
365 364 ;;
366 365 FILEPATH) if [[ -z $filepath ]]; then
367 366 filepath="$value"
368 367 fi
369 368 ;;
370 369 NFS) if [[ -z $add_nfs ]]; then
371 370 if [[ $value == 1 ]]; then
372 371 add_nfs=yes
373 372 else
374 373 add_nfs=no
375 374 fi
376 375 fi
377 376 ;;
378 377 NOKEY) if [[ -z $no_keytab ]]; then
379 378 if [[ $value == 1 ]]; then
380 379 no_keytab=yes
381 380 else
382 381 no_keytab=no
383 382 fi
384 383 fi
385 384 ;;
386 385 NOSOL) if [[ -z $non_solaris ]]; then
387 386 if [[ $value == 1 ]]; then
388 387 non_solaris=yes
389 388 no_keytab=yes
390 389 else
391 390 non_solaris=no
392 391 fi
393 392 fi
394 393 ;;
395 394 LHN) if [[ -z $logical_hn ]]; then
396 395 logical_hn="$value"
397 396 checkval="LOGICAL_HOSTNAME"
398 397 check_value $logical_hn
399 398 fi
400 399 ;;
401 400 DNSLOOKUP) if [[ -z $dnsarg ]]; then
402 401 dnsarg="$value"
403 402 checkval="DNS_OPTIONS"
404 403 check_value $dnsarg
405 404 fi
406 405 ;;
407 406 FQDN) if [[ -z $fqdnlist ]]; then
408 407 fqdnlist="$value"
409 408 checkval="FQDN"
410 409 check_value $fqdnlist
411 410 verify_fqdnlist "$fqdnlist"
412 411 fi
413 412 ;;
414 413 MSAD) if [[ -z $msad ]]; then
415 414 if [[ $value == 1 ]]; then
416 415 msad=yes
417 416 non_solaris=yes
418 417 else
419 418 msad=no
420 419 fi
421 420 fi
422 421 ;;
423 422 esac
424 423 done <$file
425 424 else
426 425 printf "\n$(gettext "The kclient profile \`%s' is not valid, exiting").\n" $file >&2
427 426 error_message
428 427 fi
429 428 }
430 429
431 430 function ping_check {
432 431 typeset machine="$1"
433 432 typeset string="$2"
434 433
435 434 if ping $machine 2 > /dev/null 2>&1; then
436 435 :
437 436 else
438 437 printf "\n$(gettext "%s %s is unreachable, exiting").\n" $string $machine >&2
439 438 error_message
440 439 fi
441 440
442 441 # Output timesync warning if not using a profile, i.e. in
443 442 # interactive mode.
444 443 if [[ -z $profile && $string == KDC ]]; then
445 444 # It's difficult to sync up time with KDC esp. if in a
446 445 # zone so just print a warning about KDC time sync.
447 446 printf "\n$(gettext "Note, this system and the KDC's time must be within 5 minutes of each other for Kerberos to function").\n" >&2
448 447 printf "$(gettext "Both systems should run some form of time synchronization system like Network Time Protocol (NTP)").\n" >&2
449 448 break
450 449 fi
451 450 }
452 451
453 452 function check_value {
454 453 typeset arg="$1"
455 454
456 455 if [[ -z $arg ]]; then
457 456 printf "\n$(gettext "No input obtained for %s, exiting").\n" $checkval >&2
458 457 error_message
459 458 else
460 459 echo "$arg" > $TMP_FILE
461 460 if egrep -s '[*$^#!]+' $TMP_FILE; then
462 461 printf "\n$(gettext "Invalid input obtained for %s, exiting").\n" $checkval >&2
463 462 error_message
464 463 fi
465 464 fi
466 465 }
467 466
468 467 function set_dns_value {
469 468 typeset -l arg="$1"
470 469
471 470 if [[ $arg == dns_lookup_kdc || $arg == dns_lookup_realm || $arg == dns_fallback ]]; then
472 471 dns_lookup=yes
473 472 else
474 473 if [[ $arg == none ]]; then
475 474 dns_lookup=no
476 475 else
477 476 printf "\n$(gettext "Invalid DNS lookup option, exiting").\n" >&2
478 477 error_message
479 478 fi
480 479 fi
481 480 }
482 481
483 482 function verify_kdcs {
484 483 typeset k_list="$1"
485 484 typeset -l kdc
486 485 typeset list fqhn f_list
487 486
488 487 kdc_list=$(echo "$k_list" | sed 's/,/ /g')
489 488
490 489 if [[ -z $k_list ]]; then
491 490 printf "\n$(gettext "At least one KDC should be listed").\n\n" >&2
492 491 usage
493 492 fi
494 493
495 494 for kdc in $k_list; do
496 495 if [[ $kdc != $KDC ]]; then
497 496 list="$list $kdc"
498 497 fkdc=`$KLOOKUP $kdc`
499 498 if ping $fkdc 2 > /dev/null; then
500 499 :
501 500 else
502 501 printf "\n$(gettext "%s %s is unreachable, no action performed").\n" "KDC" $fkdc >&2
503 502 fi
504 503 f_list="$f_list $fkdc"
505 504 fi
506 505 done
507 506
508 507 fkdc_list="$f_list"
509 508 kdc_list="$list"
510 509 }
511 510
512 511 function parse_service {
513 512 typeset service_list=$1
514 513
515 514 service_list=${service_list//,/ }
516 515 for service in $service_list; do
517 516 svc=${service%:}
518 517 auth_type=${service#:}
519 518 [[ -z $svc || -z $auth_type ]] && return
520 519 print -- $svc $auth_type
521 520 done
522 521 }
523 522
524 523 function verify_fqdnlist {
525 524 typeset list="$1"
526 525 typeset -l hostname
527 526 typeset -i count=1
528 527 typeset fqdnlist eachfqdn tmpvar fullhost
529 528
530 529 list=$(echo "$list" | tr -d " " | tr -d "\t")
531 530 hostname=$(uname -n | cut -d"." -f1)
532 531 fqdnlist=$client_machine
533 532
534 533 eachfqdn=$(echo "$list" | cut -d"," -f$count)
535 534 if [[ -z $eachfqdn ]]; then
536 535 printf "\n$(gettext "If the -f option is used, at least one FQDN should be listed").\n\n" >&2
537 536 usage
538 537 else
539 538 while [[ ! -z $eachfqdn ]]; do
540 539 tmpvar=$(echo "$eachfqdn" | cut -d"." -f1)
541 540 if [[ -z $tmpvar ]]; then
542 541 fullhost="$hostname$eachfqdn"
543 542 else
544 543 fullhost="$hostname.$eachfqdn"
545 544 fi
546 545
547 546 ping_check $fullhost $(gettext "System")
548 547 if [[ $fullhost == $client_machine ]]; then
549 548 :
550 549 else
551 550 fqdnlist="$fqdnlist $fullhost"
552 551 fi
553 552
554 553 if [[ $list == *,* ]]; then
555 554 ((count = count + 1))
556 555 eachfqdn=$(echo "$list" | cut -d"," -f$count)
557 556 else
558 557 break
559 558 fi
560 559 done
561 560 fi
562 561 }
563 562
564 563 function setup_keytab {
565 564 typeset cname ask_fqdns current_release
566 565
567 566 #
568 567 # 1. kinit with ADMIN_PRINC
569 568 #
570 569
571 570 if [[ -z $ADMIN_PRINC ]]; then
572 571 printf "\n$(gettext "Enter the krb5 administrative principal to be used"): "
573 572 read ADMIN_PRINC
574 573 checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC
575 574 fi
576 575
577 576 echo "$ADMIN_PRINC">$TMP_FILE
578 577
579 578 [[ -n $msad ]] && return
580 579 if egrep -s '\/admin' $TMP_FILE; then
581 580 # Already in "/admin" format, do nothing
582 581 :
583 582 else
584 583 if egrep -s '\/' $TMP_FILE; then
585 584 printf "\n$(gettext "Improper entry for krb5 admin principal, exiting").\n" >&2
586 585 error_message
587 586 else
588 587 ADMIN_PRINC=$(echo "$ADMIN_PRINC/admin")
589 588 fi
590 589 fi
591 590
592 591 printf "$(gettext "Obtaining TGT for %s") ...\n" $ADMIN_PRINC
593 592
594 593 cname=$(canon_resolve $KDC)
595 594 if [[ -n $cname ]]; then
596 595 kinit -S kadmin/$cname $ADMIN_PRINC
597 596 else
598 597 kinit -S kadmin/$FKDC $ADMIN_PRINC
599 598 fi
600 599 klist 1>$TMP_FILE 2>&1
601 600 if egrep -s "$(gettext "Valid starting")" $TMP_FILE && egrep -s "kadmin/$FKDC@$realm" $TMP_FILE; then
602 601 :
603 602 else
604 603 printf "\n$(gettext "kinit of %s failed, exiting").\n" $ADMIN_PRINC >&2
605 604 error_message
606 605 fi
607 606
608 607 #
609 608 # 2. Do we want to create and/or add service principal(s) for fqdn's
610 609 # other than the one listed in resolv.conf(4) ?
611 610 #
612 611 if [[ -z $options ]]; then
613 612 query "$(gettext "Do you have multiple DNS domains spanning the Kerberos realm") $realm ?"
614 613 ask_fqdns=$answer
615 614 if [[ $ask_fqdns == yes ]]; then
616 615 printf "$(gettext "Enter a comma-separated list of DNS domain names"): "
617 616 read fqdnlist
618 617 verify_fqdnlist "$fqdnlist"
619 618 else
620 619 fqdnlist=$client_machine
621 620 fi
622 621 else
623 622 if [[ -z $fqdnlist ]]; then
624 623 fqdnlist=$client_machine
625 624 fi
626 625 fi
627 626
628 627 if [[ $add_nfs == yes ]]; then
629 628 echo; call_kadmin nfs
630 629 fi
631 630
632 631 # Add the host entry to the keytab
633 632 echo; call_kadmin host
634 633
635 634 }
636 635
637 636 function setup_lhn {
638 637 typeset -l logical_hn
639 638
640 639 echo "$logical_hn" > $TMP_FILE
641 640 if egrep -s '[^.]\.[^.]+$' $TMP_FILE; then
642 641 # do nothing, logical_hn is in fqdn format
643 642 :
644 643 else
645 644 if egrep -s '\.+' $TMP_FILE; then
646 645 printf "\n$(gettext "Improper format of logical hostname, exiting").\n" >&2
647 646 error_message
648 647 else
649 648 # Attach fqdn to logical_hn, to get the Fully Qualified
650 649 # Host Name of the client requested
651 650 logical_hn=$(echo "$logical_hn.$fqdn")
652 651 fi
653 652 fi
654 653
655 654 client_machine=$logical_hn
656 655
657 656 ping_check $client_machine $(gettext "System")
658 657 }
659 658
660 659 function usage {
661 660 printf "\n$(gettext "Usage: kclient [ options ]")\n" >&2
662 661 printf "\t$(gettext "where options are any of the following")\n\n" >&2
663 662 printf "\t$(gettext "[ -D domain_list ] configure a client that has mul
664 663 tiple mappings of doamin and/or hosts to the default realm")\n" >&2
665 664 printf "\t$(gettext "[ -K ] configure a client that does not have host/service keys")\n" >&2
666 665 printf "\t$(gettext "[ -R realm ] specifies the realm to use")\n" >&2
667 666 printf "\t$(gettext "[ -T kdc_vendor ] specifies which KDC vendor is the server")\n" >&2
668 667 printf "\t$(gettext "[ -a adminuser ] specifies the Kerberos administrator")\n" >&2
669 668 printf "\t$(gettext "[ -c filepath ] specifies the krb5.conf path used to configure this client")\n" >&2
670 669 printf "\t$(gettext "[ -d dnsarg ] specifies which information should be looked up in DNS (dns_lookup_kdc, dns_lookup_realm, and dns_fallback)")\n" >&2
671 670 printf "\t$(gettext "[ -f fqdn_list ] specifies which domains to configure host keys for this client")\n" >&2
672 671 printf "\t$(gettext "[ -h logicalhostname ] configure the logical host name for a client that is in a cluster")\n" >&2
673 672 printf "\t$(gettext "[ -k kdc_list ] specify multiple KDCs, if -m is not used the first KDC in the list is assumed to be the master. KDC host names are used verbatim.")\n" >&2
674 673 printf "\t$(gettext "[ -m master ] master KDC server host name")\n" >&2
675 674 printf "\t$(gettext "[ -n ] configure client to be an NFS client")\n" >&2
676 675 printf "\t$(gettext "[ -p profile ] specifies which profile file to use to configure this client")\n" >&2
677 676 printf "\t$(gettext "[ -s pam_list ] update the service for Kerberos authentication")\n" >&2
678 677 error_message
679 678 }
680 679
681 680 function discover_domain {
682 681 typeset dom DOMs
683 682
684 683 if [[ -z $realm ]]; then
685 684 set -A DOMs -- `$KLOOKUP _ldap._tcp.dc._msdcs S`
686 685 else
687 686 set -A DOMs -- `$KLOOKUP _ldap._tcp.dc._msdcs.$realm S`
688 687 fi
689 688
690 689 [[ -z ${DOMs[0]} ]] && return 1
691 690
692 691 dom=${DOMs[0]}
693 692
694 693 dom=${dom#*.}
695 694 dom=${dom% *}
696 695
697 696 domain=$dom
698 697
699 698 return 0
700 699 }
701 700
702 701 function check_nss_hosts_or_ipnodes_config {
703 702 typeset backend
704 703
705 704 for backend in $1
706 705 do
707 706 [[ $backend == dns ]] && return 0
708 707 done
709 708 return 1
710 709 }
711 710
712 711 function check_nss_conf {
713 712 typeset i j hosts_config
714 713
715 714 for i in hosts ipnodes
716 715 do
717 716 grep "^${i}:" /etc/nsswitch.conf|read j hosts_config
718 717 check_nss_hosts_or_ipnodes_config "$hosts_config" || return 1
719 718 done
720 719
721 720 return 0
722 721 }
723 722
724 723 function canon_resolve {
725 724 typeset name ip
726 725
727 726 name=`$KLOOKUP $1 C`
728 727 [[ -z $name ]] && name=`$KLOOKUP $1 A`
729 728 [[ -z $name ]] && return
730 729
731 730 ip=`$KLOOKUP $name I`
732 731 [[ -z $ip ]] && return
733 732 for i in $ip
734 733 do
735 734 if ping $i 2 > /dev/null 2>&1; then
736 735 break
737 736 else
738 737 i=
739 738 fi
740 739 done
741 740
742 741 cname=`$KLOOKUP $ip P`
743 742 [[ -z $cname ]] && return
744 743
745 744 print -- "$cname"
746 745 }
747 746
748 747 function rev_resolve {
749 748 typeset name ip
750 749
751 750 ip=`$KLOOKUP $1 I`
752 751
753 752 [[ -z $ip ]] && return
754 753 name=`$KLOOKUP $ip P`
755 754 [[ -z $name ]] && return
756 755
757 756 print -- $name
758 757 }
759 758
760 759 # Convert an AD-style domain DN to a DNS domainname
761 760 function dn2dns {
762 761 typeset OIFS dname dn comp components
763 762
764 763 dn=$1
765 764 dname=
766 765
767 766 OIFS="$IFS"
768 767 IFS=,
769 768 set -A components -- $1
770 769 IFS="$OIFS"
771 770
772 771 for comp in "${components[@]}"
773 772 do
774 773 [[ "$comp" == [dD][cC]=* ]] || continue
775 774 dname="$dname.${comp#??=}"
776 775 done
777 776
778 777 print ${dname#.}
779 778 }
780 779
781 780 # Form a base DN from a DNS domainname and container
782 781 function getBaseDN {
783 782 if [[ -n "$2" ]]
784 783 then
785 784 baseDN="CN=$1,$(dns2dn $2)"
786 785 else
787 786 baseDN="$(dns2dn $2)"
788 787 fi
789 788 }
790 789
791 790 # Convert a DNS domainname to an AD-style DN for that domain
792 791 function dns2dn {
793 792 typeset OIFS dn labels
794 793
795 794 OIFS="$IFS"
796 795 IFS=.
797 796 set -A labels -- $1
798 797 IFS="$OIFS"
799 798
800 799 dn=
801 800 for label in "${labels[@]}"
802 801 do
803 802 dn="${dn},DC=$label"
804 803 done
805 804
806 805 print -- "${dn#,}"
807 806 }
808 807
809 808 function getSRVs {
810 809 typeset srv port
811 810
812 811 $KLOOKUP $1 S | while read srv port
813 812 do
814 813 if ping $srv 2 > /dev/null 2>&1; then
815 814 print -- $srv $port
816 815 fi
817 816 done
818 817 }
819 818
820 819 function getKDC {
821 820 typeset j
822 821
823 822 set -A KPWs -- $(getSRVs _kpasswd._tcp.$dom.)
824 823 kpasswd=${KPWs[0]}
825 824
826 825 if [[ -n $siteName ]]
827 826 then
828 827 set -A KDCs -- $(getSRVs _kerberos._tcp.$siteName._sites.$dom.)
829 828 kdc=${KDCs[0]}
830 829 [[ -n $kdc ]] && return
831 830 fi
832 831
833 832 # No site name
834 833 set -A KDCs -- $(getSRVs _kerberos._tcp.$dom.)
835 834 kdc=${KDCs[0]}
836 835 [[ -n $kdc ]] && return
837 836
838 837 # Default
839 838 set -A KDCs -- $DomainDnsZones 88
840 839 kdc=$ForestDnsZones
841 840 }
842 841
843 842 function getDC {
844 843 typeset j
845 844
846 845 if [[ -n $siteName ]]
847 846 then
848 847 set -A DCs -- $(getSRVs _ldap._tcp.$siteName._sites.dc._msdcs.$dom.)
849 848 dc=${DCs[0]}
850 849 [[ -n $dc ]] && return
851 850 fi
852 851
853 852 # No site name
854 853 set -A DCs -- $(getSRVs _ldap._tcp.dc._msdcs.$dom.)
855 854 dc=${DCs[0]}
856 855 [[ -n $dc ]] && return
857 856
|
↓ open down ↓ |
649 lines elided |
↑ open up ↑ |
858 857 # Default
859 858 set -A DCs -- $DomainDnsZones 389
860 859 dc=$DomainDnsZones
861 860 }
862 861
863 862 function write_ads_krb5conf {
864 863 printf "\n$(gettext "Setting up %s").\n\n" $KRB5_CONFIG_FILE
865 864
866 865 exec 3>$KRB5_CONFIG
867 866 if [[ $? -ne 0 ]]; then
868 - printf "\n$(gettext "Can not write to %s, exiting").\n" $KRB5_CONFIG
867 + printf "\n$(gettext "Can not write to %s, exiting").\n" $KRB5_CONFIG >&2
869 868 error_message
870 869 fi
871 870
872 871 printf "[libdefaults]\n" 1>&3
873 872 printf "\tdefault_realm = $realm\n" 1>&3
874 873 printf "\n[realms]\n" 1>&3
875 874 printf "\t$realm = {\n" 1>&3
876 875 for i in ${KDCs[@]}
877 876 do
878 877 [[ $i == +([0-9]) ]] && continue
879 878 printf "\t\tkdc = $i\n" 1>&3
880 879 done
881 880 # Defining the same as admin_server. This would cause auth failures
882 881 # if this was different.
883 882 printf "\n\t\tkpasswd_server = $KDC\n" 1>&3
884 883 printf "\n\t\tadmin_server = $KDC\n" 1>&3
885 884 printf "\t\tkpasswd_protocol = SET_CHANGE\n\t}\n" 1>&3
886 885 printf "\n[domain_realm]\n" 1>&3
887 886 printf "\t.$dom = $realm\n\n" 1>&3
888 887 printf "[logging]\n" 1>&3
889 888 printf "\tdefault = FILE:/var/krb5/kdc.log\n" 1>&3
890 889 printf "\tkdc = FILE:/var/krb5/kdc.log\n" 1>&3
891 890 printf "\tkdc_rotate = {\n\t\tperiod = 1d\n\t\tversions = 10\n\t}\n\n" 1>&3
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
892 891 printf "[appdefaults]\n" 1>&3
893 892 printf "\tkinit = {\n\t\trenewable = true\n\t\tforwardable = true\n\t}\n" 1>&3
894 893 }
895 894
896 895 function getForestName {
897 896 ldapsearch -R -T -h $dc $ldap_args \
898 897 -b "" -s base "" schemaNamingContext| \
899 898 grep ^schemaNamingContext|read j schemaNamingContext
900 899
901 900 if [[ $? -ne 0 ]]; then
902 - printf "$(gettext "Can't find forest").\n"
901 + printf "$(gettext "Can't find forest").\n" >&2
903 902 error_message
904 903 fi
905 904 schemaNamingContext=${schemaNamingContext#CN=Schema,CN=Configuration,}
906 905
907 906 [[ -z $schemaNamingContext ]] && return 1
908 907
909 908 forest=
910 909 while [[ -n $schemaNamingContext ]]
911 910 do
912 911 schemaNamingContext=${schemaNamingContext#DC=}
913 912 forest=${forest}.${schemaNamingContext%%,*}
914 913 [[ "$schemaNamingContext" = *,* ]] || break
915 914 schemaNamingContext=${schemaNamingContext#*,}
916 915 done
917 916 forest=${forest#.}
918 917 }
919 918
920 919 function getGC {
921 920 typeset j
922 921
923 922 [[ -n $gc ]] && return 0
924 923
925 924 if [[ -n $siteName ]]
926 925 then
927 926 set -A GCs -- $(getSRVs _ldap._tcp.$siteName._sites.gc._msdcs.$forest.)
928 927 gc=${GCs[0]}
929 928 [[ -n $gc ]] && return
930 929 fi
931 930
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
932 931 # No site name
933 932 set -A GCs -- $(getSRVs _ldap._tcp.gc._msdcs.$forest.)
934 933 gc=${GCs[0]}
935 934 [[ -n $gc ]] && return
936 935
937 936 # Default
938 937 set -A GCs -- $ForestDnsZones 3268
939 938 gc=$ForestDnsZones
940 939 }
941 940
941 +#
942 +# The local variables used to calculate the IP address are of type unsigned
943 +# integer (-ui), as this is required to restrict the integer to 32b.
944 +# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b.
945 +#
942 946 function ipAddr2num {
943 947 typeset OIFS
944 - typeset -i16 num byte
948 + typeset -ui16 num
945 949
946 950 if [[ "$1" != +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]]
947 951 then
948 952 print 0
949 953 return 0
950 954 fi
951 955
952 956 OIFS="$IFS"
953 957 IFS=.
954 958 set -- $1
955 959 IFS="$OIFS"
956 960
957 961 num=$((${1}<<24 | ${2}<<16 | ${3}<<8 | ${4}))
958 962
959 963 print -- $num
960 964 }
961 965
966 +#
967 +# The local variables used to calculate the IP address are of type unsigned
968 +# integer (-ui), as this is required to restrict the integer to 32b.
969 +# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b.
970 +#
962 971 function num2ipAddr {
963 - typeset -i16 num
964 - typeset -i10 a b c d
972 + typeset -ui16 num
973 + typeset -ui10 a b c d
965 974
966 975 num=$1
967 976 a=$((num>>24 ))
968 977 b=$((num>>16 & 16#ff))
969 978 c=$((num>>8 & 16#ff))
970 979 d=$((num & 16#ff))
971 980 print -- $a.$b.$c.$d
972 981 }
973 982
983 +#
984 +# The local variables used to calculate the IP address are of type unsigned
985 +# integer (-ui), as this is required to restrict the integer to 32b.
986 +# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b.
987 +#
974 988 function netmask2length {
975 - typeset -i16 netmask
989 + typeset -ui16 netmask
976 990 typeset -i len
977 991
978 992 netmask=$1
979 993 len=32
980 994 while [[ $((netmask % 2)) -eq 0 ]]
981 995 do
982 996 netmask=$((netmask>>1))
983 997 len=$((len - 1))
984 998 done
985 999 print $len
986 1000 }
987 1001
1002 +#
1003 +# The local variables used to calculate the IP address are of type unsigned
1004 +# integer (-ui), as this is required to restrict the integer to 32b.
1005 +# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b.
1006 +#
988 1007 function getSubnets {
989 - typeset -i16 addr netmask
990 - typeset -i16 classa=16\#ff000000
1008 + typeset -ui16 addr netmask
1009 + typeset -ui16 classa=16\#ff000000
991 1010
992 1011 ifconfig -a|while read line
993 1012 do
994 1013 addr=0
995 1014 netmask=0
996 1015 set -- $line
997 1016 [[ $1 == inet ]] || continue
998 1017 while [[ $# -gt 0 ]]
999 1018 do
1000 1019 case "$1" in
1001 1020 inet) addr=$(ipAddr2num $2); shift;;
1002 1021 netmask) eval netmask=16\#$2; shift;;
1003 1022 *) :;
1004 1023 esac
1005 1024 shift
1006 1025 done
1007 1026
1008 1027 [[ $addr -eq 0 || $netmask -eq 0 ]] && continue
1009 1028 [[ $((addr & classa)) -eq 16\#7f000000 ]] && continue
1010 1029
1011 1030 print $(num2ipAddr $((addr & netmask)))/$(netmask2length $netmask)
1012 1031 done
1013 1032 }
1014 1033
1015 1034 function getSite {
1016 1035 typeset subnet siteDN j ldapsrv subnet_dom
1017 1036
1018 1037 eval "[[ -n \"\$siteName\" ]]" && return
1019 1038 for subnet in $(getSubnets)
1020 1039 do
1021 1040 ldapsearch -R -T -h $dc $ldap_args \
1022 1041 -p 3268 -b "" -s sub cn=$subnet dn |grep ^dn|read j subnetDN
1023 1042
1024 1043 [[ -z $subnetDN ]] && continue
1025 1044 subnet_dom=$(dn2dns $subnetDN)
1026 1045 ldapsrv=$(canon_resolve DomainDnsZones.$subnet_dom)
1027 1046 [[ -z $ldapsrv ]] && continue
1028 1047 ldapsearch -R -T -h $ldapsrv $ldap_args \
1029 1048 -b "$subnetDN" -s base "" siteObject \
1030 1049 |grep ^siteObject|read j siteDN
1031 1050
1032 1051 [[ -z $siteDN ]] && continue
1033 1052
1034 1053 eval siteName=${siteDN%%,*}
1035 1054 eval siteName=\${siteName#CN=}
1036 1055 return
1037 1056 done
1038 1057 }
1039 1058
1040 1059 function doKRB5config {
1041 1060 [[ -f $KRB5_CONFIG_FILE ]] && \
1042 1061 cp $KRB5_CONFIG_FILE ${KRB5_CONFIG_FILE}-pre-kclient
1043 1062
1044 1063 [[ -f $KRB5_KEYTAB_FILE ]] && \
1045 1064 cp $KRB5_KEYTAB_FILE ${KRB5_KEYTAB_FILE}-pre-kclient
1046 1065
1047 1066 [[ -s $KRB5_CONFIG ]] && cp $KRB5_CONFIG $KRB5_CONFIG_FILE
1048 1067 [[ -s $KRB5_CONFIG_FILE ]] && chmod 0644 $KRB5_CONFIG_FILE
1049 1068 [[ -s $new_keytab ]] && cp $new_keytab $KRB5_KEYTAB_FILE
1050 1069 [[ -s $KRB5_KEYTAB_FILE ]] && chmod 0600 $KRB5_KEYTAB_FILE
1051 1070 }
1052 1071
1053 1072 function addDNSRR {
1054 1073 smbFMRI=svc:/network/smb/server:default
1055 1074 ddnsProp=smbd/ddns_enable
1056 1075 enProp=general/enabled
1057 1076
1058 1077 enabled=`svcprop -p $enProp $smbFMRI`
1059 1078 ddns_enable=`svcprop -p $ddnsProp $smbFMRI`
1060 1079
1061 1080 if [[ $enabled == true && $ddns_enable != true ]]; then
1062 1081 printf "$(gettext "Warning: won't create DNS records for client").\n"
1063 1082 printf "$(gettext "%s property not set to 'true' for the %s FMRI").\n" $ddnsProp $smbFMRI
1064 1083 return
1065 1084 fi
1066 1085
1067 1086 # Destroy any existing ccache as GSS_C_NO_CREDENTIAL will pick up any
1068 1087 # residual default credential in the cache.
1069 1088 kdestroy > /dev/null 2>&1
1070 1089
1071 1090 $KDYNDNS -d $1 > /dev/null 2>&1
1072 1091 if [[ $? -ne 0 ]]; then
1073 1092 #
1074 1093 # Non-fatal, we should carry-on as clients may resolve to
1075 1094 # different servers and the client could already exist there.
1076 1095 #
1077 1096 printf "$(gettext "Warning: unable to create DNS records for client").\n"
1078 1097 printf "$(gettext "This could mean that '%s' is not included as a 'nameserver' in the /etc/resolv.conf file or some other type of error").\n" $dc
1079 1098 fi
1080 1099 }
1081 1100
1082 1101 function setSMB {
1083 1102 typeset domain=$1
1084 1103 typeset server=$2
1085 1104 smbFMRI=svc:/network/smb/server
1086 1105
1087 1106 printf "%s" $newpw | $KSMB -d $domain -s $server
1088 1107 if [[ $? -ne 0 ]]; then
1089 1108 printf "$(gettext "Warning: unable to set %s domain, server and password information").\n" $smbFMRI
1090 1109 return
1091 1110 fi
1092 1111
1093 1112 svcadm restart $smbFMRI > /dev/null 2>&1
1094 1113 if [[ $? -ne 0 ]]; then
1095 1114 printf "$(gettext "Warning: unable to restart %s").\n" $smbFMRI
1096 1115 fi
1097 1116 }
1098 1117
1099 1118 function compareDomains {
1100 1119 typeset oldDom hspn newDom=$1
1101 1120
1102 1121 # If the client has been previously configured in a different
1103 1122 # realm/domain then we need to prompt the user to see if they wish to
1104 1123 # switch domains.
|
↓ open down ↓ |
104 lines elided |
↑ open up ↑ |
1105 1124 klist -k 2>&1 | grep @ | read j hspn
1106 1125 [[ -z $hspn ]] && return
1107 1126
1108 1127 oldDom=${hspn#*@}
1109 1128 if [[ $oldDom != $newDom ]]; then
1110 1129 printf "$(gettext "The client is currently configured in a different domain").\n"
1111 1130 printf "$(gettext "Currently in the '%s' domain, trying to join the '%s' domain").\n" $oldDom $newDom
1112 1131 query "$(gettext "Do you want the client to join a new domain") ?"
1113 1132 printf "\n"
1114 1133 if [[ $answer != yes ]]; then
1115 - printf "$(gettext "Client will not be joined to the new domain").\n"
1134 + printf "$(gettext "Client will not be joined to the new domain").\n" >&2
1116 1135 error_message
1117 1136 fi
1118 1137 fi
1119 1138 }
1120 1139
1121 1140 function getKDCDC {
1122 1141
1123 1142 getKDC
1124 1143 if [[ -n $kdc ]]; then
1125 1144 KDC=$kdc
1126 1145 dc=$kdc
1127 1146 else
1128 1147 getDC
1129 1148 if [[ -n $dc ]]; then
1130 1149 KDC=$dc
1131 1150 else
1132 - printf "$(gettext "Could not find domain controller server for '%s'. Exiting").\n" $realm
1151 + printf "$(gettext "Could not find domain controller server for '%s'. Exiting").\n" $realm >&2
1133 1152 error_message
1134 1153 fi
1135 1154 fi
1136 1155 }
1137 1156
1138 1157 function join_domain {
1139 1158 typeset -u upcase_nodename
1140 1159 typeset netbios_nodename fqdn
1141 1160
1142 1161 container=Computers
1143 1162 ldap_args="-o authzid= -o mech=gssapi"
1144 1163 userAccountControlBASE=4096
1145 1164
1146 1165 if [[ -z $ADMIN_PRINC ]]; then
1147 1166 cprinc=Administrator
1148 1167 else
1149 1168 cprinc=$ADMIN_PRINC
1150 1169 fi
1151 1170
1152 1171 if ! discover_domain; then
1153 - printf "$(gettext "Can not find realm") '%s'.\n" $realm
1172 + printf "$(gettext "Can not find realm") '%s'.\n" $realm >&2
1154 1173 error_message
1155 1174 fi
1156 1175
1157 1176 dom=$domain
1158 1177 realm=$domain
1159 1178 upcase_nodename=$hostname
1160 1179 netbios_nodename="${upcase_nodename}\$"
1161 1180 fqdn=$hostname.$domain
1162 1181 upn=host/${fqdn}
1163 1182
1164 1183 grep=/usr/xpg4/bin/grep
1165 1184
1166 1185 object=$(mktemp -q -t kclient-computer-object.XXXXXX)
1167 1186 if [[ -z $object ]]; then
1168 1187 printf "\n$(gettext "Can not create temporary file, exiting").\n
1169 1188 " >&2
1170 1189 error_message
1171 1190 fi
1172 1191
1173 1192 grep=/usr/xpg4/bin/grep
1174 1193
1175 1194 modify_existing=false
1176 1195 recreate=false
1177 1196
1178 1197 DomainDnsZones=$(rev_resolve DomainDnsZones.$dom.)
1179 1198 ForestDnsZones=$(rev_resolve ForestDnsZones.$dom.)
1180 1199
1181 1200 getBaseDN "$container" "$dom"
1182 1201
1183 1202 if [[ -n $KDC ]]; then
1184 1203 dc=$KDC
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
1185 1204 else
1186 1205 getKDCDC
1187 1206 fi
1188 1207
1189 1208 write_ads_krb5conf
1190 1209
1191 1210 printf "$(gettext "Attempting to join '%s' to the '%s' domain").\n\n" $upcase_nodename $realm
1192 1211
1193 1212 kinit $cprinc@$realm
1194 1213 if [[ $? -ne 0 ]]; then
1195 - printf "$(gettext "Could not authenticate %s. Exiting").\n" $cprinc@$realm
1214 + printf "$(gettext "Could not authenticate %s. Exiting").\n" $cprinc@$realm >&2
1196 1215 error_message
1197 1216 fi
1198 1217
1199 1218 if getForestName
1200 1219 then
1201 1220 printf "\n$(gettext "Forest name found: %s")\n\n" $forest
1202 1221 else
1203 1222 printf "\n$(gettext "Forest name not found, assuming forest is the domain name").\n"
1204 1223 fi
1205 1224
1206 1225 getGC
1207 1226 getSite
1208 1227
1209 1228 if [[ -z $siteName ]]
1210 1229 then
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
1211 1230 printf "$(gettext "Site name not found. Local DCs/GCs will not be discovered").\n\n"
1212 1231 else
1213 1232 printf "$(gettext "Looking for _local_ KDCs, DCs and global catalog servers (SRV RRs)").\n"
1214 1233 getKDCDC
1215 1234 getGC
1216 1235
1217 1236 write_ads_krb5conf
1218 1237 fi
1219 1238
1220 1239 if [[ ${#GCs} -eq 0 ]]; then
1221 - printf "$(gettext "Could not find global catalogs. Exiting").\n"
1240 + printf "$(gettext "Could not find global catalogs. Exiting").\n" >&2
1222 1241 error_message
1223 1242 fi
1224 1243
1225 1244 # Check to see if the client is transitioning between domains.
1226 1245 compareDomains $realm
1227 1246
1228 1247 # Here we check domainFunctionality to see which release:
1229 1248 # 0, 1, 2: Windows 2000, 2003 Interim, 2003 respecitively
1230 1249 # 3: Windows 2008
1231 1250 level=0
1232 1251 ldapsearch -R -T -h "$dc" $ldap_args -b "" -s base "" \
1233 1252 domainControllerFunctionality| grep ^domainControllerFunctionality| \
1234 1253 read j level
1235 1254 if [[ $? -ne 0 ]]; then
1236 - printf "$(gettext "Search for domain functionality failed, exiting").\n"
1255 + printf "$(gettext "Search for domain functionality failed, exiting").\n" >&2
1237 1256 error_message
1238 1257 fi
1239 1258 # Longhorn and above can't perform an init auth from service
1240 1259 # keys if the realm is included in the UPN. w2k3 and below
1241 1260 # can't perform an init auth when the realm is excluded.
1242 1261 [[ $level -lt 3 ]] && upn=${upn}@${realm}
1243 1262
1244 1263 if ldapsearch -R -T -h "$dc" $ldap_args -b "$baseDN" \
1245 1264 -s sub sAMAccountName="$netbios_nodename" dn > /dev/null 2>&1
1246 1265 then
1247 1266 :
1248 1267 else
1249 - printf "$(gettext "Search for node failed, exiting").\n"
1268 + printf "$(gettext "Search for node failed, exiting").\n" >&2
1250 1269 error_message
1251 1270 fi
1252 1271 ldapsearch -R -T -h "$dc" $ldap_args -b "$baseDN" -s sub \
1253 1272 sAMAccountName="$netbios_nodename" dn|grep "^dn:"|read j dn
1254 1273
1255 1274 if [[ -z $dn ]]; then
1256 1275 : # modify_existing is already false, which is what we want.
1257 1276 else
1258 1277 printf "$(gettext "Computer account '%s' already exists in the '%s' domain").\n" $upcase_nodename $realm
1259 1278 query "$(gettext "Do you wish to recreate this computer account") ?"
1260 1279 printf "\n"
1261 1280 if [[ $answer == yes ]]; then
1262 1281 recreate=true
1263 1282 else
1264 1283 modify_existing=true
1265 1284 fi
1266 1285 fi
1267 1286
1268 1287 if [[ $modify_existing == false && -n $dn ]]; then
1269 1288 query "$(gettext "Would you like to delete any sub-object found for this computer account") ?"
1270 1289 if [[ $answer == yes ]]; then
1271 1290 printf "$(gettext "Looking to see if the machine account contains other objects")...\n"
1272 1291 ldapsearch -R -T -h "$dc" $ldap_args -b "$dn" -s sub "" dn | while read j sub_dn
1273 1292 do
1274 1293 [[ $j != dn: || -z $sub_dn || $dn == $sub_dn ]] && continue
1275 1294 if $recreate; then
1276 1295 printf "$(gettext "Deleting the following object: %s")\n" ${sub_dn#$dn}
1277 1296 ldapdelete -h "$dc" $ldap_args "$sub_dn" > /dev/null 2>&1
1278 1297 if [[ $? -ne 0 ]]; then
1279 1298 printf "$(gettext "Error in deleting object: %s").\n" ${sub_dn#$dn}
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
1280 1299 fi
1281 1300 else
1282 1301 printf "$(gettext "The following object will not be deleted"): %s\n" ${sub_dn#$dn}
1283 1302 fi
1284 1303 done
1285 1304 fi
1286 1305
1287 1306 if $recreate; then
1288 1307 ldapdelete -h "$dc" $ldap_args "$dn" > /dev/null 2>&1
1289 1308 if [[ $? -ne 0 ]]; then
1290 - printf "$(gettext "Error in deleting object: %s").\n" ${sub_dn#$dn}
1309 + printf "$(gettext "Error in deleting object: %s").\n" ${sub_dn#$dn} >&2
1291 1310 error_message
1292 1311 fi
1293 1312 elif $modify_existing; then
1294 1313 : # Nothing to delete
1295 1314 else
1296 - printf "$(gettext "A machine account already exists").\n"
1315 + printf "$(gettext "A machine account already exists").\n" >&2
1297 1316 error_message
1298 1317 fi
1299 1318 fi
1300 1319
1301 1320 if $modify_existing; then
1302 1321 cat > "$object" <<EOF
1303 1322 dn: CN=$upcase_nodename,$baseDN
1304 1323 changetype: modify
1305 1324 replace: userPrincipalName
1306 1325 userPrincipalName: $upn
1307 1326 -
1308 1327 replace: servicePrincipalName
1309 1328 servicePrincipalName: host/${fqdn}
1310 1329 -
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1311 1330 replace: userAccountControl
1312 1331 userAccountControl: $((userAccountControlBASE + 32 + 2))
1313 1332 -
1314 1333 replace: dNSHostname
1315 1334 dNSHostname: ${fqdn}
1316 1335 EOF
1317 1336
1318 1337 printf "$(gettext "A machine account already exists; updating it").\n"
1319 1338 ldapadd -h "$dc" $ldap_args -f "$object" > /dev/null 2>&1
1320 1339 if [[ $? -ne 0 ]]; then
1321 - printf "$(gettext "Failed to create the AD object via LDAP").\n"
1340 + printf "$(gettext "Failed to create the AD object via LDAP").\n" >&2
1322 1341 error_message
1323 1342 fi
1324 1343 else
1325 1344 cat > "$object" <<EOF
1326 1345 dn: CN=$upcase_nodename,$baseDN
1327 1346 objectClass: computer
1328 1347 cn: $upcase_nodename
1329 1348 sAMAccountName: ${netbios_nodename}
1330 1349 userPrincipalName: $upn
1331 1350 servicePrincipalName: host/${fqdn}
1332 1351 userAccountControl: $((userAccountControlBASE + 32 + 2))
1333 1352 dNSHostname: ${fqdn}
1334 1353 EOF
1335 1354
1336 1355 printf "$(gettext "Creating the machine account in AD via LDAP").\n\n"
1337 1356
1338 1357 ldapadd -h "$dc" $ldap_args -f "$object" > /dev/null 2>&1
1339 1358 if [[ $? -ne 0 ]]; then
1340 - printf "$(gettext "Failed to create the AD object via LDAP").\n"
1359 + printf "$(gettext "Failed to create the AD object via LDAP").\n" >&2
1341 1360 error_message
1342 1361 fi
1343 1362 fi
1344 1363
1345 1364 # Generate a new password for the new account
1346 1365 MAX_PASS=32
1347 1366 i=0
1348 1367
1349 1368 while :
1350 1369 do
1351 1370 while ((MAX_PASS > i))
1352 1371 do
1353 1372 # 94 elements in the printable character set starting
1354 1373 # at decimal 33, contiguous.
1355 1374 dig=$((RANDOM%94+33))
1356 1375 c=$(printf "\\`printf %o $dig`\n")
1357 1376 p=$p$c
1358 1377 ((i+=1))
1359 1378 done
1360 1379
1361 1380 # Ensure that we have four character classes.
1362 1381 d=${p%[[:digit:]]*}
1363 1382 a=${p%[[:lower:]]*}
1364 1383 A=${p%[[:upper:]]*}
1365 1384 x=${p%[[:punct:]]*}
1366 1385
1367 1386 # Just compare the number of characters from what was previously
1368 1387 # matched. If there is a difference then we found a match.
1369 1388 n=${#p}
1370 1389 [[ ${#d} -ne $n && ${#a} -ne $n && \
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
1371 1390 ${#A} -ne $n && ${#x} -ne $n ]] && break
1372 1391 i=0
1373 1392 p=
1374 1393 done
1375 1394 newpw=$p
1376 1395
1377 1396 # Set the new password
1378 1397 printf "%s" $newpw | $KSETPW ${netbios_nodename}@${realm} > /dev/null 2>&1
1379 1398 if [[ $? -ne 0 ]]
1380 1399 then
1381 - printf "$(gettext "Failed to set account password").\n"
1400 + printf "$(gettext "Failed to set account password").\n" >&2
1382 1401 error_message
1383 1402 fi
1384 1403
1385 1404 # Lookup the new principal's kvno:
1386 1405 ldapsearch -R -T -h "$dc" $ldap_args -b "$baseDN" \
1387 1406 -s sub cn=$upcase_nodename msDS-KeyVersionNumber| \
1388 1407 grep "^msDS-KeyVersionNumber"|read j kvno
1389 1408 [[ -z $kvno ]] && kvno=1
1390 1409
1391 1410 # Set supported enctypes. This only works for Longhorn/Vista, so we
1392 1411 # ignore errors here.
1393 1412 userAccountControl=$((userAccountControlBASE + 524288 + 65536))
1394 1413 set -A enctypes --
1395 1414
1396 1415 # Do we have local support for AES?
1397 1416 encrypt -l|grep ^aes|read j minkeysize maxkeysize
1398 1417 val=
1399 1418 if [[ $maxkeysize -eq 256 ]]; then
1400 1419 val=16
1401 1420 enctypes[${#enctypes[@]}]=aes256-cts-hmac-sha1-96
1402 1421 fi
1403 1422 if [[ $minkeysize -eq 128 ]]; then
1404 1423 ((val=val+8))
1405 1424 enctypes[${#enctypes[@]}]=aes128-cts-hmac-sha1-96
1406 1425 fi
1407 1426
1408 1427 # RC4 comes next (whether it's better than 1DES or not -- AD prefers it)
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
1409 1428 if encrypt -l|$grep -q ^arcfour
1410 1429 then
1411 1430 ((val=val+4))
1412 1431 enctypes[${#enctypes[@]}]=arcfour-hmac-md5
1413 1432 else
1414 1433 # Use 1DES ONLY if we don't have arcfour
1415 1434 userAccountControl=$((userAccountControl + 2097152))
1416 1435 fi
1417 1436 if encrypt -l | $grep -q ^des
1418 1437 then
1419 - ((val=val+1+2))
1420 - enctypes[${#enctypes[@]}]=des-cbc-crc
1438 + ((val=val+2))
1421 1439 enctypes[${#enctypes[@]}]=des-cbc-md5
1422 1440 fi
1423 1441
1424 1442 if [[ ${#enctypes[@]} -eq 0 ]]
1425 1443 then
1426 1444 printf "$(gettext "No enctypes are supported").\n"
1427 - printf "$(gettext "Please enable arcfour or 1DES, then re-join; see cryptoadm(1M)").\n"
1445 + printf "$(gettext "Please enable arcfour or 1DES, then re-join; see cryptoadm(1M)").\n" >&2
1428 1446 error_message
1429 1447 fi
1430 1448
1431 1449 # If domain crontroller is Longhorn or above then set new supported
1432 1450 # encryption type attributes.
1433 1451 if [[ $level -gt 2 ]]; then
1434 1452 cat > "$object" <<EOF
1435 1453 dn: CN=$upcase_nodename,$baseDN
1436 1454 changetype: modify
1437 1455 replace: msDS-SupportedEncryptionTypes
1438 1456 msDS-SupportedEncryptionTypes: $val
1439 1457 EOF
1440 1458 ldapmodify -h "$dc" $ldap_args -f "$object" >/dev/null 2>&1
1441 1459 if [[ $? -ne 0 ]]; then
1442 1460 printf "$(gettext "Warning: Could not set the supported encryption type for computer account").\n"
1443 1461 fi
1444 1462 fi
1445 1463
1446 1464 # We should probably check whether arcfour is available, and if not,
1447 1465 # then set the 1DES only flag, but whatever, it's not likely NOT to be
1448 1466 # available on S10/Nevada!
1449 1467
1450 1468 # Reset userAccountControl
1451 1469 #
1452 1470 # NORMAL_ACCOUNT (512) | DONT_EXPIRE_PASSWORD (65536) |
1453 1471 # TRUSTED_FOR_DELEGATION (524288)
1454 1472 #
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
1455 1473 # and possibly UseDesOnly (2097152) (see above)
1456 1474 #
1457 1475 cat > "$object" <<EOF
1458 1476 dn: CN=$upcase_nodename,$baseDN
1459 1477 changetype: modify
1460 1478 replace: userAccountControl
1461 1479 userAccountControl: $userAccountControl
1462 1480 EOF
1463 1481 ldapmodify -h "$dc" $ldap_args -f "$object" >/dev/null 2>&1
1464 1482 if [[ $? -ne 0 ]]; then
1465 - printf "$(gettext "ldapmodify failed to modify account attribute").\n"
1483 + printf "$(gettext "ldapmodify failed to modify account attribute").\n" >&2
1466 1484 error_message
1467 1485 fi
1468 1486
1469 1487 # Setup a keytab file
1470 1488 set -A args --
1471 1489 for enctype in "${enctypes[@]}"
1472 1490 do
1473 1491 args[${#args[@]}]=-e
1474 1492 args[${#args[@]}]=$enctype
1475 1493 done
1476 1494
1477 1495 rm $new_keytab > /dev/null 2>&1
1478 1496
1479 1497 cat > "$object" <<EOF
1480 1498 dn: CN=$upcase_nodename,$baseDN
1481 1499 changetype: modify
1482 1500 add: servicePrincipalName
1483 1501 servicePrincipalName: nfs/${fqdn}
1484 1502 servicePrincipalName: HTTP/${fqdn}
1485 1503 servicePrincipalName: root/${fqdn}
1504 +servicePrincipalName: cifs/${fqdn}
1486 1505 EOF
1487 1506 ldapmodify -h "$dc" $ldap_args -f "$object" >/dev/null 2>&1
1488 1507 if [[ $? -ne 0 ]]; then
1489 - printf "$(gettext "ldapmodify failed to modify account attribute").\n"
1508 + printf "$(gettext "ldapmodify failed to modify account attribute").\n" >&2
1490 1509 error_message
1491 1510 fi
1492 1511
1493 - printf "%s" $newpw | $KSETPW -n -v $kvno -k "$new_keytab" "${args[@]}" host/${fqdn}@${realm} > /dev/null 2>&1
1512 + #
1513 + # In Windows, unlike MIT based implementations we salt the keys with
1514 + # the UPN, which is based on the host/fqdn@realm elements, not with the
1515 + # individual SPN strings.
1516 + #
1517 + salt=host/${fqdn}@${realm}
1518 +
1519 + printf "%s" $newpw | $KSETPW -n -s $salt -v $kvno -k "$new_keytab" "${args[@]}" host/${fqdn}@${realm} > /dev/null 2>&1
1494 1520 if [[ $? -ne 0 ]]
1495 1521 then
1496 - printf "$(gettext "Failed to set account password").\n"
1522 + printf "$(gettext "Failed to set account password").\n" >&2
1497 1523 error_message
1498 1524 fi
1499 1525
1526 + printf "%s" $newpw | $KSETPW -n -s $salt -v $kvno -k "$new_keytab" "${args[@]}" HOST/${fqdn}@${realm} > /dev/null 2>&1
1527 + if [[ $? -ne 0 ]]
1528 + then
1529 + printf "$(gettext "Failed to set account password").\n" >&2
1530 + error_message
1531 + fi
1532 +
1500 1533 # Could be setting ${netbios_nodename}@${realm}, but for now no one
1501 1534 # is requesting this.
1502 1535
1503 - print "%s" $newpw | $KSETPW -n -v $kvno -k "$new_keytab" "${args[@]}" nfs/${fqdn}@${realm} > /dev/null 2>&1
1536 + printf "%s" $newpw | $KSETPW -n -s $salt -v $kvno -k "$new_keytab" "${args[@]}" nfs/${fqdn}@${realm} > /dev/null 2>&1
1504 1537 if [[ $? -ne 0 ]]
1505 1538 then
1506 - printf "$(gettext "Failed to set account password").\n"
1539 + printf "$(gettext "Failed to set account password").\n" >&2
1507 1540 error_message
1508 1541 fi
1509 1542
1510 - print "%s" $newpw | $KSETPW -n -v $kvno -k "$new_keytab" "${args[@]}" HTTP/${fqdn}@${realm} > /dev/null 2>&1
1543 + printf "%s" $newpw | $KSETPW -n -s $salt -v $kvno -k "$new_keytab" "${args[@]}" HTTP/${fqdn}@${realm} > /dev/null 2>&1
1511 1544 if [[ $? -ne 0 ]]
1512 1545 then
1513 - printf "$(gettext "Failed to set account password").\n"
1546 + printf "$(gettext "Failed to set account password").\n" >&2
1514 1547 error_message
1515 1548 fi
1516 1549
1517 - print "%s" $newpw | $KSETPW -n -v $kvno -k "$new_keytab" "${args[@]}" root/${fqdn}@${realm} > /dev/null 2>&1
1550 + printf "%s" $newpw | $KSETPW -n -s $salt -v $kvno -k "$new_keytab" "${args[@]}" root/${fqdn}@${realm} > /dev/null 2>&1
1518 1551 if [[ $? -ne 0 ]]
1519 1552 then
1520 - printf "$(gettext "Failed to set account password").\n"
1553 + printf "$(gettext "Failed to set account password").\n" >&2
1521 1554 error_message
1522 1555 fi
1523 1556
1557 + printf "%s" $newpw | $KSETPW -n -s $salt -v $kvno -k "$new_keytab" "${args[@]}" cifs/${fqdn}@${realm} > /dev/null 2>&1
1558 + if [[ $? -ne 0 ]]
1559 + then
1560 + printf "$(gettext "Failed to set account password").\n" >&2
1561 + error_message
1562 + fi
1563 +
1524 1564 doKRB5config
1525 1565
1526 1566 addDNSRR $dom
1527 1567
1528 1568 setSMB $dom $dc
1529 1569
1530 1570 printf -- "\n---------------------------------------------------\n"
1531 1571 printf "$(gettext "Setup COMPLETE").\n\n"
1532 1572
1533 1573 kdestroy -q 1>$TMP_FILE 2>&1
1534 1574 rm -f $TMP_FILE
1535 1575 rm -rf $TMPDIR > /dev/null 2>&1
1536 1576
1537 1577 exit 0
1538 1578 }
1539 1579
1540 1580 ###########################
1541 1581 # Main section #
1542 1582 ###########################
1543 1583 #
1544 1584 # Set the Kerberos config file and some default strings/files
1545 1585 #
1546 1586 KRB5_CONFIG_FILE=/etc/krb5/krb5.conf
1547 1587 KRB5_KEYTAB_FILE=/etc/krb5/krb5.keytab
1548 1588 RESOLV_CONF_FILE=/etc/resolv.conf
1549 1589
1550 1590 KLOOKUP=/usr/lib/krb5/klookup; check_bin $KLOOKUP
1551 1591 KSETPW=/usr/lib/krb5/ksetpw; check_bin $KSETPW
1552 1592 KSMB=/usr/lib/krb5/ksmb; check_bin $KSMB
1553 1593 KDYNDNS=/usr/lib/krb5/kdyndns; check_bin $KDYNDNS
1554 1594
1555 1595 dns_lookup=no
1556 1596 ask_fqdns=no
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
1557 1597 adddns=no
1558 1598 no_keytab=no
1559 1599 checkval=""
1560 1600 profile=""
1561 1601 typeset -u realm
1562 1602 typeset -l hostname KDC
1563 1603
1564 1604 export TMPDIR="/var/run/kclient"
1565 1605
1566 1606 mkdir $TMPDIR > /dev/null 2>&1
1607 +if [[ $? -ne 0 ]]; then
1608 + printf "\n$(gettext "Can not create directory: %s")\n\n" $TMPDIR >&2
1609 + exit 1
1610 +fi
1567 1611
1568 1612 TMP_FILE=$(mktemp -q -t kclient-tmpfile.XXXXXX)
1569 1613 export KRB5_CONFIG=$(mktemp -q -t kclient-krb5conf.XXXXXX)
1570 1614 export KRB5CCNAME=$(mktemp -q -t kclient-krb5ccache.XXXXXX)
1571 1615 new_keytab=$(mktemp -q -t kclient-krb5keytab.XXXXXX)
1572 1616 if [[ -z $TMP_FILE || -z $KRB5_CONFIG || -z $KRB5CCNAME || -z $new_keytab ]]
1573 1617 then
1574 - printf "\n$(gettext "Can not create temporary file, exiting").\n" >&2
1575 - error_message
1618 + printf "\n$(gettext "Can not create temporary files, exiting").\n\n" >&2
1619 + exit 1
1576 1620 fi
1577 1621
1578 1622 #
1579 1623 # If we are interrupted, cleanup after ourselves
1580 1624 #
1581 1625 trap "exiting 1" HUP INT QUIT TERM
1582 1626
1583 1627 if [[ -d /usr/bin ]]; then
1584 1628 if [[ -d /usr/sbin ]]; then
1585 1629 PATH=/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
1586 1630 export PATH
1587 1631 else
1588 1632 printf "\n$(gettext "Directory /usr/sbin not found, exiting").\n" >&2
1589 1633 exit 1
1590 1634 fi
1591 1635 else
1592 1636 printf "\n$(gettext "Directory /usr/bin not found, exiting").\n" >&2
1593 1637 exit 1
1594 1638 fi
1595 1639
1596 1640 printf "\n$(gettext "Starting client setup")\n\n"
1597 1641 printf -- "---------------------------------------------------\n"
1598 1642
1599 1643 #
1600 1644 # Check for uid 0, disallow otherwise
1601 1645 #
1602 1646 id 1>$TMP_FILE 2>&1
1603 1647 if [[ $? -eq 0 ]]; then
1604 1648 if egrep -s "uid=0\(root\)" $TMP_FILE; then
1605 1649 # uid is 0, go ahead ...
1606 1650 :
1607 1651 else
1608 1652 printf "\n$(gettext "Administrative privileges are required to run this script, exiting").\n" >&2
1609 1653 error_message
1610 1654 fi
1611 1655 else
1612 1656 cat $TMP_FILE;
1613 1657 printf "\n$(gettext "uid check failed, exiting").\n" >&2
1614 1658 error_message
1615 1659 fi
1616 1660
1617 1661 uname=$(uname -n)
1618 1662 hostname=${uname%%.*}
1619 1663
1620 1664 #
1621 1665 # Process the command-line arguments (if any)
1622 1666 #
1623 1667 OPTIND=1
1624 1668 while getopts nD:Kp:R:k:a:c:d:f:h:m:s:T: OPTIONS
1625 1669 do
1626 1670 case $OPTIONS in
1627 1671 D) options="$options -D"
1628 1672 domain_list="$OPTARG"
1629 1673 ;;
1630 1674 K) options="$options -K"
1631 1675 no_keytab=yes
1632 1676 ;;
1633 1677 R) options="$options -R"
1634 1678 realm="$OPTARG"
1635 1679 checkval="REALM"; check_value $realm
1636 1680 ;;
1637 1681 T) options="$options -T"
1638 1682 type="$OPTARG"
1639 1683 if [[ $type == ms_ad ]]; then
1640 1684 msad=yes
1641 1685 adddns=yes
1642 1686 else
1643 1687 non_solaris=yes
1644 1688 no_keytab=yes
1645 1689 fi
1646 1690 ;;
1647 1691 a) options="$options -a"
1648 1692 ADMIN_PRINC="$OPTARG"
1649 1693 checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC
1650 1694 ;;
1651 1695 c) options="$options -c"
1652 1696 filepath="$OPTARG"
1653 1697 ;;
1654 1698 d) options="$options -d"
1655 1699 dnsarg="$OPTARG"
1656 1700 checkval="DNS_OPTIONS"; check_value $dnsarg
1657 1701 ;;
1658 1702 f) options="$options -f"
1659 1703 fqdnlist="$OPTARG"
1660 1704 ;;
1661 1705 h) options="$options -h"
1662 1706 logical_hn="$OPTARG"
1663 1707 checkval="LOGICAL_HOSTNAME"; check_value $logical_hn
1664 1708 ;;
1665 1709 k) options="$options -k"
1666 1710 kdc_list="$OPTARG"
1667 1711 ;;
1668 1712 m) options="$options -m"
1669 1713 KDC="$OPTARG"
1670 1714 checkval="KDC"; check_value $KDC
1671 1715 ;;
1672 1716 n) options="$options -n"
1673 1717 add_nfs=yes
1674 1718 ;;
1675 1719 p) options="$options -p"
1676 1720 profile="$OPTARG"
1677 1721 read_profile $profile
1678 1722 ;;
1679 1723 s) options="$options -s"
1680 1724 svc_list="$OPTARG"
1681 1725 SVCs=${svc_list//,/ }
1682 1726 ;;
1683 1727 \?) usage
1684 1728 ;;
1685 1729 *) usage
1686 1730 ;;
1687 1731 esac
1688 1732 done
1689 1733
1690 1734 #correct argument count after options
1691 1735 shift `expr $OPTIND - 1`
1692 1736
1693 1737 if [[ -z $options ]]; then
1694 1738 :
1695 1739 else
1696 1740 if [[ $# -ne 0 ]]; then
1697 1741 usage
1698 1742 fi
1699 1743 fi
1700 1744
1701 1745 #
1702 1746 # Check to see if we will be a client of a MIT, Heimdal, Shishi, etc.
1703 1747 #
1704 1748 if [[ -z $options ]]; then
1705 1749 query "$(gettext "Is this a client of a non-Solaris KDC") ?"
1706 1750 non_solaris=$answer
1707 1751 if [[ $non_solaris == yes ]]; then
1708 1752 printf "$(gettext "Which type of KDC is the server"):\n"
1709 1753 printf "\t$(gettext "ms_ad: Microsoft Active Directory")\n"
1710 1754 printf "\t$(gettext "mit: MIT KDC server")\n"
1711 1755 printf "\t$(gettext "heimdal: Heimdal KDC server")\n"
1712 1756 printf "\t$(gettext "shishi: Shishi KDC server")\n"
1713 1757 printf "$(gettext "Enter required KDC type"): "
1714 1758 read kdctype
1715 1759 if [[ $kdctype == ms_ad ]]; then
1716 1760 msad=yes
1717 1761 elif [[ $kdctype == mit || $kdctype == heimdal || \
1718 1762 $kdctype == shishi ]]; then
1719 1763 no_keytab=yes
1720 1764 else
1721 1765 printf "\n$(gettext "Invalid KDC type option, valid types are ms_ad, mit, heimdal, or shishi, exiting").\n" >&2
1722 1766 error_message
1723 1767 fi
1724 1768 fi
1725 1769 fi
1726 1770
1727 1771 [[ $msad == yes ]] && join_domain
1728 1772
1729 1773 #
1730 1774 # Check for /etc/resolv.conf
1731 1775 #
1732 1776 if [[ -r $RESOLV_CONF_FILE ]]; then
1733 1777 client_machine=`$KLOOKUP`
1734 1778
1735 1779 if [[ $? -ne 0 ]]; then
1736 1780 if [[ $adddns == no ]]; then
1737 1781 printf "\n$(gettext "%s does not have a DNS record and is required for Kerberos setup")\n" $hostname >&2
1738 1782 error_message
1739 1783 fi
1740 1784
1741 1785 else
1742 1786 #
1743 1787 # If client entry already exists then do not recreate it
1744 1788 #
1745 1789 adddns=no
1746 1790
1747 1791 hostname=${client_machine%%.*}
1748 1792 domain=${client_machine#*.}
1749 1793 fi
1750 1794
1751 1795 short_fqdn=${domain#*.*}
1752 1796 short_fqdn=$(echo $short_fqdn | grep "\.")
1753 1797 else
1754 1798 #
1755 1799 # /etc/resolv.conf not present, exit ...
1756 1800 #
1757 1801 printf "\n$(gettext "%s does not exist and is required for Kerberos setup")\n" $RESOLV_CONF_FILE >&2
1758 1802 printf "$(gettext "Refer to resolv.conf(4), exiting").\n" >&2
1759 1803 error_message
1760 1804 fi
1761 1805
1762 1806 check_nss_conf || printf "$(gettext "/etc/nsswitch.conf does not make use of DNS for hosts and/or ipnodes").\n"
1763 1807
1764 1808 [[ -n $fqdnlist ]] && verify_fqdnlist "$fqdnlist"
1765 1809
1766 1810 if [[ -z $dnsarg && (-z $options || -z $filepath) ]]; then
1767 1811 query "$(gettext "Do you want to use DNS for kerberos lookups") ?"
1768 1812 if [[ $answer == yes ]]; then
1769 1813 printf "\n$(gettext "Valid DNS lookup options are dns_lookup_kdc, dns_lookup_realm,\nand dns_fallback. Refer krb5.conf(4) for further details").\n"
1770 1814 printf "\n$(gettext "Enter required DNS option"): "
1771 1815 read dnsarg
1772 1816 checkval="DNS_OPTIONS"; check_value $dnsarg
1773 1817 set_dns_value $dnsarg
1774 1818 fi
1775 1819 else
1776 1820 [[ -z $dnsarg ]] && dnsarg=none
1777 1821 set_dns_value $dnsarg
1778 1822 fi
1779 1823
1780 1824 if [[ -n $kdc_list ]]; then
1781 1825 if [[ -z $KDC ]]; then
1782 1826 for kdc in $kdc_list; do
1783 1827 break
1784 1828 done
1785 1829 KDC="$kdc"
1786 1830 fi
1787 1831 fi
1788 1832
1789 1833 if [[ -z $realm ]]; then
1790 1834 printf "$(gettext "Enter the Kerberos realm"): "
1791 1835 read realm
1792 1836 checkval="REALM"; check_value $realm
1793 1837 fi
1794 1838 if [[ -z $KDC ]]; then
1795 1839 printf "$(gettext "Specify the master KDC hostname for the above realm"): "
1796 1840 read KDC
1797 1841 checkval="KDC"; check_value $KDC
1798 1842 fi
1799 1843
1800 1844 FKDC=`$KLOOKUP $KDC`
1801 1845
1802 1846 #
1803 1847 # Ping to see if the kdc is alive !
1804 1848 #
1805 1849 ping_check $FKDC "KDC"
1806 1850
1807 1851 if [[ -z $kdc_list && (-z $options || -z $filepath) ]]; then
1808 1852 query "$(gettext "Do you have any slave KDC(s)") ?"
1809 1853 if [[ $answer == yes ]]; then
1810 1854 printf "$(gettext "Enter a comma-separated list of slave KDC host names"): "
1811 1855 read kdc_list
1812 1856 fi
1813 1857 fi
1814 1858
1815 1859 [[ -n $kdc_list ]] && verify_kdcs "$kdc_list"
1816 1860
1817 1861 #
1818 1862 # Check to see if we will have a dynamic presence in the realm
1819 1863 #
1820 1864 if [[ -z $options ]]; then
1821 1865 query "$(gettext "Will this client need service keys") ?"
1822 1866 if [[ $answer == no ]]; then
1823 1867 no_keytab=yes
1824 1868 fi
1825 1869 fi
1826 1870
1827 1871 #
1828 1872 # Check to see if we are configuring the client to use a logical host name
1829 1873 # of a cluster environment
1830 1874 #
1831 1875 if [[ -z $options ]]; then
1832 1876 query "$(gettext "Is this client a member of a cluster that uses a logical host name") ?"
1833 1877 if [[ $answer == yes ]]; then
1834 1878 printf "$(gettext "Specify the logical hostname of the cluster"): "
1835 1879 read logical_hn
1836 1880 checkval="LOGICAL_HOSTNAME"; check_value $logical_hn
1837 1881 setup_lhn
1838 1882 fi
1839 1883 fi
1840 1884
1841 1885 if [[ -n $domain_list && (-z $options || -z $filepath) ]]; then
1842 1886 query "$(gettext "Do you have multiple domains/hosts to map to realm %s"
1843 1887 ) ?" $realm
1844 1888 if [[ $answer == yes ]]; then
1845 1889 printf "$(gettext "Enter a comma-separated list of domain/hosts
1846 1890 to map to the default realm"): "
1847 1891 read domain_list
1848 1892 fi
1849 1893 fi
1850 1894 [[ -n domain_list ]] && domain_list=${domain_list//,/ }
1851 1895
1852 1896 #
1853 1897 # Start writing up the krb5.conf file, save the existing one
1854 1898 # if already present
1855 1899 #
1856 1900 writeup_krb5_conf
1857 1901
1858 1902 #
1859 1903 # Is this client going to use krb-nfs? If so then we need to at least
1860 1904 # uncomment the krb5* sec flavors in nfssec.conf.
1861 1905 #
1862 1906 if [[ -z $options ]]; then
1863 1907 query "$(gettext "Do you plan on doing Kerberized nfs") ?"
1864 1908 add_nfs=$answer
1865 1909 fi
1866 1910
1867 1911 if [[ $add_nfs == yes ]]; then
1868 1912 modify_nfssec_conf
1869 1913
1870 1914 #
1871 1915 # We also want to enable gss as we now live in a SBD world
1872 1916 #
1873 1917 svcadm enable svc:/network/rpc/gss:default
1874 1918 [[ $? -ne 0 ]] && printf "$(gettext "Warning: could not enable gss service").\n"
1875 1919 fi
1876 1920
1877 1921 if [[ -z $options ]]; then
1878 1922 query "$(gettext "Do you want to update /etc/pam.conf") ?"
1879 1923 if [[ $answer == yes ]]; then
1880 1924 printf "$(gettext "Enter a list of PAM service names in the following format: service:{first|only|optional}[,..]"): "
1881 1925 read svc_list
1882 1926 SVCs=${svc_list//,/ }
1883 1927 fi
1884 1928 fi
1885 1929 [[ -n $svc_list ]] && update_pam_conf
1886 1930
1887 1931 #
1888 1932 # Copy over krb5.conf master copy from filepath
1889 1933 #
1890 1934 if [[ -z $options || -z $filepath ]]; then
1891 1935 query "$(gettext "Do you want to copy over the master krb5.conf file") ?"
1892 1936 if [[ $answer == yes ]]; then
1893 1937 printf "$(gettext "Enter the pathname of the file to be copied"): "
1894 1938 read filepath
1895 1939 fi
1896 1940 fi
1897 1941
1898 1942 if [[ -n $filepath && -r $filepath ]]; then
1899 1943 cp $filepath $KRB5_CONFIG
1900 1944 if [[ $? -eq 0 ]]; then
1901 1945 printf "$(gettext "Copied %s to %s").\n" $filepath $KRB5_CONFIG
1902 1946 else
1903 1947 printf "$(gettext "Copy of %s failed, exiting").\n" $filepath >&2
1904 1948 error_message
1905 1949 fi
1906 1950 elif [[ -n $filepath ]]; then
1907 1951 printf "\n$(gettext "%s not found, exiting").\n" $filepath >&2
1908 1952 error_message
1909 1953 fi
1910 1954
1911 1955 doKRB5config
1912 1956
1913 1957 #
1914 1958 # Populate any service keys needed for the client in the keytab file
1915 1959 #
1916 1960 if [[ $no_keytab != yes ]]; then
1917 1961 setup_keytab
1918 1962 else
1919 1963 printf "\n$(gettext "Note: %s file not created, please refer to verify_ap_req_nofail in krb5.conf(4) for the implications").\n" $KRB5_KEYTAB_FILE
1920 1964 printf "$(gettext "Client will also not be able to host services that use Kerberos").\n"
1921 1965 fi
1922 1966
1923 1967 printf -- "\n---------------------------------------------------\n"
1924 1968 printf "$(gettext "Setup COMPLETE").\n\n"
1925 1969
1926 1970 #
1927 1971 # If we have configured the client in a cluster we need to remind the user
1928 1972 # to propagate the keytab and configuration files to the other members.
1929 1973 #
1930 1974 if [[ -n $logical_hn ]]; then
1931 1975 printf "\n$(gettext "Note, you will need to securely transfer the /etc/krb5/krb5.keytab and /etc/krb5/krb5.conf files to all the other members of your cluster").\n"
1932 1976 fi
1933 1977
1934 1978 #
1935 1979 # Cleanup.
1936 1980 #
1937 1981 kdestroy -q 1>$TMP_FILE 2>&1
1938 1982 rm -f $TMP_FILE
1939 1983 rm -rf $TMPDIR > /dev/null 2>&1
1940 1984 exit 0
|
↓ open down ↓ |
355 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX